Files
Calendink/Provider/GEMINI.md

4.9 KiB

Calendink Provider — Agent Context

This is an ESP32-S3 IoT device firmware + web dashboard project. It uses ESP-IDF (native, not Arduino) and serves a Svelte 5 web UI from flash.


Project Summary

Calendink Provider is a connected desk device that serves a local web dashboard over Ethernet/WiFi. The firmware manages network connections, serves a Svelte SPA from LittleFS flash partitions, and exposes a REST API for system control (reboot, OTA, tasks, users).

Key Paths

Path Purpose
main/ C++ firmware (Unity Build)
main/api/ REST API handlers, one file per endpoint
main/http_server.cpp HTTP server setup, static file serving
main/connect.cpp Ethernet + WiFi connection management
frontend/src/ Svelte 5 frontend source
frontend/src/lib/api.js All API calls (always use trackedFetch)
frontend/src/app.css TailwindCSS v4 design tokens (@theme)
tdd/ Technical Design Documents (read before major changes)
.agents/rules/ Coding guidelines (always follow)

Architecture

Backend

  • Unity Build: main.cpp #includes all .cpp files. Do NOT add files to CMakeLists.txt. Everything is one translation unit.
  • API handlers: Each endpoint is its own .cpp file in main/api/<domain>/. A unity.cpp aggregates them.
  • HTTP server: esp_http_server + cJSON. CORS is always on (*).
  • Data storage: Users and tasks are in static BSS arrays (g_Users[8], g_Tasks[32]). In-RAM only, intentionally — persistence is a future feature.
  • OTA: A/B partition scheme — www_0 / www_1 for frontend, ota_0 / ota_1 for firmware. NVS tracks which slot is active.
  • Connections: Ethernet first, WiFi fallback. Connection state managed with FreeRTOS semaphores.

Frontend

  • Svelte 5 with runes ($state, $derived, $effect, $props). No legacy Svelte 4 APIs.
  • TailwindCSS v4 (utility classes only — no <style> blocks in components).
  • Single-file build: vite-plugin-singlefile inlines all JS+CSS into one index.html.
  • Version: Tracked in version.json, injected as __APP_VERSION__ at build time.
  • Dev mode: Set VITE_API_BASE=http://<ESP32_IP> in .env.development — the frontend runs on PC and calls the real ESP32 API.

Coding Rules (summary — full rules in .agents/rules/coding-guidelines.md)

Backend

  • C-style code: no classes, no std::, no RAII, no exceptions. Use template, auto, constexpr freely.
  • Use internal (= static) for all file-scoped symbols.
  • Log with ESP_LOGI/W/E only — never printf(). Name log tags per-module with unique variable names (e.g., kTagHttpServer), not a shared TAG, to avoid Unity Build redefinition.
  • Seed data (seed_users, seed_tasks) must be #ifndef NDEBUG guarded.

Frontend

  • Svelte 5 runes only. No onMount, onDestroy, writable, .subscribe.
  • Tailwind only. No <style> blocks.
  • Shared logic goes in lib/utils.js. Never duplicate functions across components.
  • API calls go through lib/api.js via trackedFetch() — never raw fetch().
  • $state() for values the template reads. Plain let for script-only flags/handles.

Technical Design Documents

Always read the relevant TDD before making major architectural changes:

TDD When to read
backend_architecture.md Changing server setup, adding new API groups
frontend_technology_choices.md Changing build tools, adding dependencies
todo_list.md Changing task/user data models or API contracts
firmware_ota.md Touching OTA partition logic
frontend_ota.md Touching frontend OTA upload or versioning
concurrent_requests.md Changing HTTP server socket/connection config

How to Work With the User

  • After finishing any task: tell the user what you did, what you think the next step should be, and ask for approval before proceeding.
  • Never go rogue — propose changes, wait for confirmation.
  • Write a TDD before major architectural changes. See .agents/rules/how-to-write-tdd.md.
  • Keep AGENTS.md and GEMINI.md up to date. If a task changes the architecture, adds new rules, introduces new build commands, or modifies the project layout — update both files before closing the task.

Build Commands

# Backend — from project root
idf.py build
idf.py flash monitor

# Frontend — from frontend/
npm run dev                # Dev server (PC, calls real ESP32 API)
npm run build              # Production build → dist/index.html
npm run build:esp32        # Build + gzip → dist/index.html.gz
npm run ota:package        # Package as versioned .bin
npm run ota:bundle         # Package FW + frontend as .bundle
npm run ota:deploy         # Deploy frontend OTA to device