Files
labtimesheet/README.md

140 lines
6.8 KiB
Markdown

# Lab Timesheet
Server-rendered Spring Boot application for managing laboratory internships,
Projects, Tasks, and attendance. Iteration 1 is complete and was verified on
15 August 2026.
## Iteration 1: working now
### Accounts and onboarding
- Atomic first-Admin bootstrap that remains closed after initialization and restart.
- Optional SMTP onboarding with five distinct deferral warnings and a persistent restricted-state notice.
- Admin SMTP draft, connection test, and activation against Mailpit or another configured server.
- Admin creation of Admin, Mentor, and Intern accounts through single-use email activation.
- Password setup, form login, logout, global roles, and role-protected Admin routes.
### Projects
- Owning Mentors create `PLANNED` Projects with an eligible initial Leader.
- Mentor-controlled direct membership with historical membership and leadership intervals.
- Leader reassignment and guarded `PLANNED` to `ACTIVE` activation.
- Role-correct Project lists, details, member views, and guessed-ID concealment.
### Tasks
- One current assignee per Task.
- Active members create self-assigned Tasks; the current Leader may assign another active member.
- Due dates are checked against Project dates and current global days off.
- The fixed `TODO`, `IN_PROGRESS`, `BLOCKED`, and `DONE` transition graph is enforced.
- Authorized comments, Task lists/details, assignee display, status counts, and completion progress.
### Attendance and calendar
- Effective attendance-policy resolution with Vietnam business time, configured workdays, and separate 30-minute check-in and checkout grace defaults.
- Admin-managed manual global calendar days off.
- Server-time check-in and checkout with duplicate, off-day, leave-day, lifecycle, and cutoff rejection.
- `MISSING_CHECKOUT` classification without a second early-departure violation.
- Intern history plus authorized Mentor/Admin attendance inspection using the historical applied policy.
### Desktop UI
- Shared Thymeleaf/Tailwind shell with role-aware navigation and dashboards.
- Light, dark, and system themes applied before paint.
- Collapsible desktop sidebar, accessible forms/errors, tables, badges, empty states, and local Lucide icons.
- Bootstrap, authentication, SMTP, Project, Task, calendar, and attendance pages integrated into the same shell.
## Deliberately not implemented yet
The baseline schema includes later-workflow tables; table presence does not mean
the corresponding feature is complete.
- Iteration 2: Project invitations and approved membership exits, broader Project lifecycle transfers, Task edit/delete/reassignment and work logs, leave, missed-checkout corrections, notifications, schedulers, and complete metrics.
- Iteration 3: HTML/XLSX/PDF report parity, Chart.js trends, production security hardening, application containers, Compose, Gitea CI publication, and deployment scaffolding.
- Mobile layouts are best-effort. Desktop is the supported interface target.
## Architecture and versions
- Java 25, Spring Boot 4.1.0, Maven, Spring MVC/Security/Data JPA/Validation, Thymeleaf, Flyway, and PostgreSQL 18.4.
- Node 24/npm 11, Tailwind CSS 4.3.3, and `lucide-static` 1.27.0 for local assets.
- Package-by-feature modular monolith under `com.lab.labtimesheet.feature`.
- Cross-feature access through public services and DTOs; no cross-feature repositories, shadow entities, or business SQL.
- Flyway owns the schema; Hibernate validates it with `ddl-auto=validate`.
## Local development
Follow [DEVELOPMENT.md](DEVELOPMENT.md) for the complete beginner-friendly
setup, PostgreSQL and Mailpit container commands, terminal launch steps, and an
IntelliJ IDEA run-configuration walkthrough.
The committed [`.env.example`](.env.example) contains placeholders only. Real
database passwords and the AES-256 master key belong in an untracked `.env`.
Product SMTP and HolidayAPI credentials are configured through the Admin
console, not environment variables.
```bash
cp .env.example .env
# Edit .env. Generate LAB_SECURITY_MASTER_KEY with: openssl rand -base64 32
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="/opt/homebrew/opt/node@24/bin:$JAVA_HOME/bin:$PATH"
npm ci
npm run build
./mvnw spring-boot:run
```
Development defaults to the application on port `8080`, PostgreSQL on `55432`,
and Mailpit SMTP on `1025`. The exact Spring settings are in
[`application-dev.yaml`](src/main/resources/application-dev.yaml), which imports
the ignored root `.env` file when the `dev` profile is active.
On first launch, open `http://localhost:8080`; the application redirects to
`/bootstrap`, where you create the first Admin. Then configure and test SMTP or
complete all five explicit deferral warnings.
## Verification status
The final Iteration 1 integration gate recorded:
- 197 Maven tests passed with PostgreSQL 18.4 Testcontainers.
- Flyway replay produced exactly 23 application tables and 56 foreign keys.
- Java compilation and full Javadoc/doclint passed.
- Two consecutive Node/Tailwind/Lucide builds produced identical assets.
- A real Java process completed bootstrap, login, SMTP deferral, persistent warning recovery, and a separate Mailpit draft/test/activate flow with health `UP`.
- Independent reviews of all five work branches closed with no remaining Critical, Important, or Minor findings.
Tests require Docker for PostgreSQL Testcontainers:
```bash
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export DOCKER_HOST=unix:///Users/your-name/.orbstack/run/docker.sock # only when using OrbStack
./mvnw test
```
See [TESTING.md](TESTING.md) for setup, test commands, the required TDD cycle,
evidence records, best practices, and common fixes. Every behavior test has a
companion record under [`docs/tests`](docs/tests/README.md).
## Branch ownership
| Branch | Primary area |
|---|---|
| `work/platform` | Application baseline, schema, accounts, security, integrations |
| `work/projects` | Projects, membership, leadership, lifecycle |
| `work/tasks` | Tasks, comments, status, progress |
| `work/attendance` | Policy, calendar, attendance workflows |
| `work/reports-ui` | Shared UI, dashboards, reporting presentation |
For a targeted repair, create a clean isolated branch and worktree from the
taskmaster-verified current `main` named
`work/fix/<feature>/<what-fix>`. Do not nest it as
`work/<feature>/fix/<what-fix>`: the persistent `work/<feature>` ref already
uses that Git ref prefix.
Every targeted repair starts from the taskmaster-verified latest `main`, uses TDD RED → GREEN, adds Javadoc during implementation, records companion evidence, undergoes independent review, and uses a normal, non-force merge only when separately authorized.
Iteration 2 work must start from the merged Iteration 1 `main`, continue with
strict RED-to-GREEN TDD, add Javadoc during implementation, and update the
matching Markdown evidence record before each milestone commit.