Goal-Calibration/ai/frontend-context.md

2.4 KiB

Frontend context

Read ai/shared.md first. This file only covers frontend-specific rules.

Project Context

Stack: vanilla PHP templates in views/templates/, plain ES JavaScript in public/js/, no framework, no build step. Cypress 15 for E2E. Entry point: public/index.php (Slim app); page templates are rendered via the existing templating layer.

Code patterns

  • Look at existing pages (home.php/home.js, text.php/text.js, today.php/today.js) for reference before writing anything
  • Templates: views/templates/<page>.php, one file per page
  • Page JS: public/js/<page>.js, one file per page, paired with the matching template
  • Testing: Cypress E2E only, mirror existing cypress/e2e/*.cy.js style (note: this project uses .cy.js, not .cy.ts)
  • Imports / script tags: keep at the top of the file
  • Variable names: explicit, descriptive (e.g. text not t)

Pre-commit

No JS formatter or linter is configured yet; format manually for consistency with surrounding files. (TODO: wire up format/lint when added.)

Note on commit granularity

Frontend changes are often a template plus its page-level JS counterpart - commit them together as a single logical unit, per the "one logical change per commit" rule in shared.md.

LLM anti-patterns

Constructs LLMs default to that this project forbids on the frontend.

Anti-pattern Forbidden Required
Short variable name t, n, res, req, e, el, ev text, node, response, request, submitEvent, element, clickEvent
Em dash in code/comments // loads texts — owner only // loads texts - owner only
Inline <script> in templates <script>doStuff()</script> in a .php template put logic in public/js/<page>.js, load via <script src=...>
Hardcoded admin URLs in user-facing JS fetch('/api/admin/...') from a non-admin page JS call user-scoped endpoints from user pages, admin endpoints only from admin pages
Cypress test logging in as the wrong role cy.loginAsAdmin() in a non-admin spec match the role to the page under test (loginAsUser for /home, /texts; loginAsAdmin for /admin/*)
cy.request in E2E tests cy.request('/api/...') to set up state or assert tests must exercise UI - drive via cy.visit/cy.get; if seeding is needed, add it to backend seed data

When generating code, scan the diff for these patterns before writing it to disk.