Stop invoking the unavailable formatter and remove factory usage for the missing user factory. Give PHPStan workers the same memory allowance as the development shell.
191 lines
7.1 KiB
Markdown
191 lines
7.1 KiB
Markdown
# Shared rules
|
|
|
|
Rules that apply to both backend and frontend work in this repository.
|
|
Stack-specific guides (`backend-context.md`, `frontend-context.md`) extend
|
|
these rules.
|
|
|
|
## Project state
|
|
|
|
- Attainly is in early development.
|
|
- Attainly helps users break hierarchical goals into scheduled assignments,
|
|
complete daily work, and track progress toward a target date.
|
|
- Schedule recalculation must preserve completed work while redistributing
|
|
unfinished assignments across the remaining dates.
|
|
- Planned features in `README.md` are future ideas, not authorized scope.
|
|
- The Laravel backend exists under `backend/`.
|
|
- The standalone Vue frontend exists under `frontend/website/`.
|
|
- Keep the frontend independent from the backend. Do not add backend-driven
|
|
rendering, asset delivery, or build integration unless the user explicitly
|
|
asks for it.
|
|
- PostgreSQL is the development and runtime database.
|
|
- PHPUnit uses in-memory SQLite for isolated tests.
|
|
|
|
## Process (TDD)
|
|
|
|
0. Before editing any file, ensure you are working in a dedicated git
|
|
worktree, not the main checkout (`git status` and `git worktree list`).
|
|
If on `master`/`main` or in the main working directory, create a worktree
|
|
first (see Branching).
|
|
1. Write the test first.
|
|
2. Run the test to confirm it fails for the expected reason.
|
|
3. Commit the failing test. The test commit must precede the implementation
|
|
commit, not merely appear earlier in the implementation diff.
|
|
4. Implement the smallest change that makes the test pass.
|
|
5. Run the test to confirm it passes.
|
|
6. Commit the implementation.
|
|
7. Repeat for each new behavior.
|
|
|
|
Use judgment for changes that cannot meaningfully be test-driven, such as
|
|
documentation-only edits or declarative environment configuration. Validate
|
|
those changes with the most relevant parser, formatter, dry run, or check.
|
|
|
|
## Running processes
|
|
|
|
- The main checkout owns the canonical stack on the default ports. Assume it
|
|
is the user's stack. Do not start, restart, or stop it unless the user asks.
|
|
- A worktree owns its own isolated stack. The flake shell hook assigns a
|
|
deterministic port offset and creates worktree-local PostgreSQL state.
|
|
- Start a worktree stack from its root with `process-compose up`. For
|
|
non-interactive use, run `process-compose up -D` and stop it with
|
|
`process-compose down`.
|
|
- Do not use `process-compose -t=false` for a detached stack. It can leave an
|
|
orphaned PostgreSQL process holding the data directory.
|
|
- Non-interactive agent shells do not automatically load direnv. A bare
|
|
`process-compose`, `php artisan`, or database command from a worktree can
|
|
silently use default ports and target the main checkout.
|
|
- Prefix worktree stack and database commands with `direnv exec <worktree>`.
|
|
Examples:
|
|
|
|
```sh
|
|
direnv exec <worktree> process-compose up -D
|
|
direnv exec <worktree> process-compose down
|
|
direnv exec <worktree> php artisan migrate:fresh --seed
|
|
```
|
|
|
|
- Run backend commands from `backend/`, or explicitly change into it in the
|
|
command.
|
|
- Run frontend commands from `frontend/website/`.
|
|
- `process-compose` does not start the frontend. Start it separately with
|
|
`npm run dev -- --port "$VITE_PORT"` when needed.
|
|
- When a normally valid check fails because a required service is down,
|
|
surface the environmental failure. Do not skip the check or silently switch
|
|
to a different database or service.
|
|
- PHPUnit is self-contained and uses in-memory SQLite. It does not require the
|
|
PostgreSQL stack unless a future test is explicitly designed as a real
|
|
PostgreSQL integration test.
|
|
|
|
## Code style
|
|
|
|
- Keep lines at or below 80 columns where practical. Do not split short,
|
|
readable lines unnecessarily.
|
|
- Use explicit, descriptive variable names. Do not use single-letter or
|
|
unexplained abbreviated names.
|
|
- Explore the codebase and inspect similar files before implementing a new
|
|
pattern.
|
|
- Never use em dashes in code, comments, or docblocks. Use hyphens.
|
|
- Always use braced control-statement bodies, including early returns:
|
|
|
|
```ts
|
|
if (identifier === null) {
|
|
return null
|
|
}
|
|
```
|
|
|
|
## Git commit style
|
|
|
|
- Use present-tense, imperative subjects: `add`, `create`, `wire`, `fix`,
|
|
`test`.
|
|
- Keep subjects lowercase and short, normally three to six words.
|
|
- Match patterns in the existing git history.
|
|
- Do not add AI or tool coauthor trailers.
|
|
- Add a body when the subject cannot explain non-obvious motivation or
|
|
multi-file coordination.
|
|
- Wrap bodies at approximately 72 columns and separate them from the subject
|
|
with a blank line.
|
|
|
|
## Git commits
|
|
|
|
- Commit tests before implementation.
|
|
- Keep one logical change per commit. A logical change may span multiple
|
|
files.
|
|
- Commit each meaningful step rather than batching unrelated work.
|
|
- Do not include drive-by formatter or linter changes. Restore them or land
|
|
them as a separate formatting commit.
|
|
- If a check fails on untouched code, do not bundle an unrelated fix. Report
|
|
the pre-existing failure or handle it as its own explicitly scoped change.
|
|
|
|
## Branching
|
|
|
|
- Never implement features directly in the main checkout or on
|
|
`master`/`main`.
|
|
- Use a dedicated worktree under
|
|
`<repo-root>/.worktrees/<branch>`.
|
|
- Create it with:
|
|
|
|
```sh
|
|
git worktree add \
|
|
"$(git rev-parse --show-toplevel)/.worktrees/<branch>" \
|
|
-b <branch>
|
|
```
|
|
|
|
- Use descriptive kebab-case branch names, optionally prefixed with a type
|
|
such as `feature/` or `fix/`.
|
|
- Keep worktree names short, preferably no more than about 20 characters.
|
|
PostgreSQL Unix socket paths are limited in length.
|
|
- Provision a fresh worktree through direnv:
|
|
|
|
```sh
|
|
direnv allow <worktree>
|
|
direnv exec <worktree> true
|
|
```
|
|
|
|
- Never symlink `backend/vendor` or `frontend/website/node_modules` from
|
|
another checkout. Dependency paths and generated files must remain
|
|
worktree-local.
|
|
- The shell hook installs backend dependencies but does not install frontend
|
|
dependencies. Run `npm install` from `frontend/website/` when provisioning a
|
|
fresh worktree.
|
|
|
|
Do not push anything. Make commits as the TDD workflow requires.
|
|
|
|
## Before completing a change
|
|
|
|
Run the smallest relevant checks while iterating, then run every repository
|
|
gate affected by the change.
|
|
|
|
### Backend
|
|
|
|
- Run tests from `backend/` with `php artisan test`.
|
|
- Run the Composer checks defined by `backend/composer.json`:
|
|
|
|
```sh
|
|
composer types:check
|
|
composer test
|
|
```
|
|
|
|
- Do not claim a green gate when a command fails. If the failure predates the
|
|
change, report the precise baseline failure.
|
|
|
|
### Frontend
|
|
|
|
- Run these commands from `frontend/website/`:
|
|
|
|
```sh
|
|
npm run format
|
|
npm run lint
|
|
npm run type-check
|
|
npm run build
|
|
```
|
|
|
|
- The formatter and linters rewrite files. Review their changes before
|
|
committing.
|
|
- No frontend test runner is configured yet. Do not claim unit, component, or
|
|
end-to-end test coverage until the relevant scripts exist and pass.
|
|
|
|
### Environment and integration
|
|
|
|
- For Nix or shell-hook changes, run `nix fmt` and `nix flake check`.
|
|
- For service configuration changes, run `process-compose --dry-run`.
|
|
- When a change affects runtime wiring, start the worktree's stack and verify
|
|
the relevant endpoint or service against that worktree.
|
|
- If you started the stack only for validation, stop it before finishing.
|