Remove legacy root app.js, update docs

- Delete root app.js (pre-Symfony legacy copy, no longer served anywhere)
- CLAUDE.md: remove sync instruction, drop outdated pending-cleanup items,
  add AdminController to key files, fix i18n note (DE/EN/PL), fix Twig cache note
- docs/api.md: document locale/is_admin in /api/me, PATCH locale, new
  GET /api/admin/users endpoint
- docs/structure.md: add AdminController, clean up legacy table descriptions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Simon Kühn 2026-05-01 10:09:17 +02:00
parent eea6119e36
commit ffdc983553
4 changed files with 32 additions and 1011 deletions

View file

@ -1,7 +1,7 @@
# Dudi Claude Context # Dudi Claude Context
## What this is ## What this is
Habit & goal tracking PWA. Users set goals (e.g. "50 push-ups/day for 30 days"), log sets daily, and see progress. Invite-only registration. German UI. Habit & goal tracking PWA. Users set goals (e.g. "50 push-ups/day for 30 days"), log sets daily, and see progress. Invite-only registration. Multilingual UI (DE/EN/PL).
## Stack ## Stack
- Symfony 8 + Doctrine ORM (src/) - Symfony 8 + Doctrine ORM (src/)
@ -13,7 +13,7 @@ Habit & goal tracking PWA. Users set goals (e.g. "50 push-ups/day for 30 days"),
- URL: http://dudi.local/ - URL: http://dudi.local/
- DB: zieltracker / zieltracker (see .env.local, gitignored) - DB: zieltracker / zieltracker (see .env.local, gitignored)
- `php bin/console cache:clear` after config changes - `php bin/console cache:clear` after config changes
- `public/app.js` is the authoritative JS file — also copy to `public/` after edits to `app.js` at root (root copy is legacy, will be removed) - `public/app.js` is the authoritative JS file
## Server ## Server
- `ssh -p 30183 root@miniweb.kuehn.home` - `ssh -p 30183 root@miniweb.kuehn.home`
@ -22,9 +22,10 @@ Habit & goal tracking PWA. Users set goals (e.g. "50 push-ups/day for 30 days"),
- Remember-me table must exist: `rememberme_token` (already created) - Remember-me table must exist: `rememberme_token` (already created)
## Key files ## Key files
- `src/Controller/AuthController.php` — login, register, password reset, name change - `src/Controller/AuthController.php` — login, register, password reset, name/locale change
- `src/Controller/GoalController.php` — goals CRUD - `src/Controller/GoalController.php` — goals CRUD
- `src/Controller/InviteController.php` — invite creation + listing - `src/Controller/InviteController.php` — invite creation + listing
- `src/Controller/AdminController.php` — admin-only user list (guarded by ADMIN_EMAIL env var)
- `src/Security/JsonLoginAuthenticator.php` — JSON POST /api/login - `src/Security/JsonLoginAuthenticator.php` — JSON POST /api/login
- `config/packages/security.yaml` — firewall, remember-me, access control - `config/packages/security.yaml` — firewall, remember-me, access control
- `templates/app.html.twig` — SPA shell + all tpl-* templates - `templates/app.html.twig` — SPA shell + all tpl-* templates
@ -38,11 +39,9 @@ Habit & goal tracking PWA. Users set goals (e.g. "50 push-ups/day for 30 days"),
## Conventions ## Conventions
- API responses: `{ ok: true, ... }` on success, `{ error: "message" }` on failure - API responses: `{ ok: true, ... }` on success, `{ error: "message" }` on failure
- All API routes prefixed `/api/`, catch-all route in AppController renders SPA - All API routes prefixed `/api/`, catch-all route in AppController renders SPA
- No Twig cache (cache: false in index.php, now handled by Symfony kernel in prod) - No Twig cache in dev (handled by Symfony kernel; disabled in dev env)
- JS uses `tpl(id)` helper to clone `<template>` elements, fills via querySelector with semantic class names - JS uses `tpl(id)` helper to clone `<template>` elements, fills via querySelector with semantic class names
- No comments in JS unless non-obvious; no trailing summaries in responses - No comments in JS unless non-obvious; no trailing summaries in responses
## Pending cleanup ## Pending cleanup
- `api.php`, `index.php`, `include/`, `app.js`, `style.css` at project root are legacy pre-Symfony files — safe to delete once miniweb is migrated to Symfony
- Legacy DB tables that can be dropped: `users_throttling`, `users_confirmations`, `schema_migrations` - Legacy DB tables that can be dropped: `users_throttling`, `users_confirmations`, `schema_migrations`
- miniweb still runs old non-Symfony code — Symfony deploy + Apache config update pending

1000
app.js

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@ Returns `{ ok, email, name }` or `401`.
Invalidates session. Returns `{ ok: true }`. Invalidates session. Returns `{ ok: true }`.
### `GET /api/me` ### `GET /api/me`
Returns `{ ok, email, id, name }` or `{ ok: false }` (401) if not logged in. Returns `{ ok, email, id, name, locale, is_admin }` or `{ ok: false }` (401) if not logged in.
### `PATCH /api/me` ### `PATCH /api/me`
```json ```json
@ -22,6 +22,11 @@ Returns `{ ok, email, id, name }` or `{ ok: false }` (401) if not logged in.
``` ```
Updates display name. Returns `{ ok, name }`. Updates display name. Returns `{ ok, name }`.
```json
{ "locale": "de" }
```
Updates UI language (`de`, `en`, `pl`). Returns `{ ok, locale }`.
### `POST /api/register` ### `POST /api/register`
```json ```json
{ "email": "...", "password": "...", "token": "<invite-token>", "name": "..." } { "email": "...", "password": "...", "token": "<invite-token>", "name": "..." }
@ -100,3 +105,19 @@ Returns all invites created by the authenticated user.
"used_by_email": null "used_by_email": null
}] }]
``` ```
---
## Admin
### `GET /api/admin/users`
Returns all users. Only accessible if the logged-in user's email matches `ADMIN_EMAIL` env var; returns `403` otherwise.
```json
[{
"id": 1,
"email": "user@example.com",
"username": "Max",
"registered": 1714500000
}]
```

View file

@ -23,7 +23,8 @@ dudi/
│ │ ├── AppController.php # Catch-all → renders app.html.twig │ │ ├── AppController.php # Catch-all → renders app.html.twig
│ │ ├── AuthController.php # /api/me, /api/register, /api/reset-*, /api/change-password │ │ ├── AuthController.php # /api/me, /api/register, /api/reset-*, /api/change-password
│ │ ├── GoalController.php # /api/goals CRUD │ │ ├── GoalController.php # /api/goals CRUD
│ │ └── InviteController.php # /api/invite, /api/invites │ │ ├── InviteController.php # /api/invite, /api/invites
│ │ └── AdminController.php # /api/admin/users (ADMIN_EMAIL-guarded)
│ ├── Entity/ │ ├── Entity/
│ │ ├── User.php # Maps to users table (delight-im/auth compatible schema) │ │ ├── User.php # Maps to users table (delight-im/auth compatible schema)
│ │ ├── Goal.php │ │ ├── Goal.php
@ -61,6 +62,6 @@ The frontend is a single-page app with no build step:
| `users` | Doctrine ORM | User accounts (bcrypt passwords) | | `users` | Doctrine ORM | User accounts (bcrypt passwords) |
| `rememberme_token` | Symfony Security | 24h remember-me tokens | | `rememberme_token` | Symfony Security | 24h remember-me tokens |
| `users_resets` | Raw SQL in AuthController | Password reset tokens | | `users_resets` | Raw SQL in AuthController | Password reset tokens |
| `users_throttling` | Legacy (delight-im/auth) | Can be removed | | `users_throttling` | Legacy | Can be dropped |
| `users_confirmations` | Legacy (delight-im/auth) | Can be removed | | `users_confirmations` | Legacy | Can be dropped |
| `schema_migrations` | Legacy | Can be removed | | `schema_migrations` | Legacy | Can be dropped |