openspec: frontend-foundation change — proposal, design, specs (4 capabilities), tasks

This commit is contained in:
2026-08-05 12:51:44 +10:00
parent c2d6f00241
commit b846c2c58e
9 changed files with 284 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
## ADDED Requirements
### Requirement: Shared Postgres database
The system SHALL use a single shared PostgreSQL database for all data. The canonical schema SHALL live in `db/schema.sql` until the Laravel admin takes over migration ownership.
#### Scenario: Schema applied to a fresh database
- **WHEN** `db/schema.sql` is applied to an empty database
- **THEN** the `users`, `tags`, and `scans` tables exist with the defined columns and constraints
### Requirement: Users table
The `users` table SHALL store id, unique email, password hash, name, phone, and created_at.
#### Scenario: Unique emails
- **WHEN** a second row is inserted with an email that already exists
- **THEN** the database rejects the insert
### Requirement: Tags table
The `tags` table SHALL store a unique public `tag_code`, owner reference, status (`unset`, `active`, `suspended`), item type, description, photo URL, phone, address, notes, and timestamps.
#### Scenario: Unique tag codes
- **WHEN** a second row is inserted with a tag_code that already exists
- **THEN** the database rejects the insert
#### Scenario: Status values
- **WHEN** a row is inserted with a status not in the allowed set
- **THEN** the database rejects the insert
### Requirement: Scans table
The `scans` table SHALL record tag scans with timestamp, optional latitude/longitude, whether location was shared, optional scanner phone, and whether an alert was sent.
#### Scenario: Recording a scan
- **WHEN** a scan of a tag is recorded
- **THEN** a row exists with tag reference, timestamp, and location flags

View File

@@ -0,0 +1,41 @@
## ADDED Requirements
### Requirement: Public tag page by code
The system SHALL serve an unauthenticated page at `/t/<tag_code>` for any valid tag code.
#### Scenario: Valid code
- **WHEN** a visitor opens `/t/<tag_code>` for a tag that exists
- **THEN** the tag page is rendered
#### Scenario: Unknown code
- **WHEN** a visitor opens `/t/<tag_code>` for a code that does not exist
- **THEN** a friendly "tag not found" page is shown
### Requirement: Unset tag shows setup prompt
When the tag is not yet bound to an account (status `unset`), the tag page SHALL tell the visitor the tag is not set up and show how to claim it.
#### Scenario: First scan of an unset tag
- **WHEN** a visitor opens the page of a tag with status `unset`
- **THEN** the page shows a "this tag is not set up yet" message and a link to register/log in
### Requirement: Set tag shows return details
When the tag is bound to an account and has details (status `active`), the tag page SHALL show the item's return details: item type, description, photo, phone, address, notes — for any visitor without login.
#### Scenario: Finder views an active tag
- **WHEN** a visitor opens the page of a tag with status `active`
- **THEN** the page shows the item's return details without requiring login
#### Scenario: Suspended tag
- **WHEN** a visitor opens the page of a tag with status `suspended`
- **THEN** the page shows only that the tag is unavailable
### Requirement: Owner edit affordance
A logged-in owner viewing their own tag page SHALL see an edit link to the account CRUD page for that tag.
#### Scenario: Owner is logged in
- **WHEN** the authenticated owner opens the page of their own tag
- **THEN** an edit link to the tag's edit page is shown
#### Scenario: Visitor is not the owner
- **WHEN** a visitor who is not the owner opens the page
- **THEN** no edit link is shown

View File

@@ -0,0 +1,44 @@
## ADDED Requirements
### Requirement: Add a tag to the account
An authenticated owner SHALL be able to bind a tag to their account by entering its tag code. A tag that is already bound to another account SHALL be rejected.
#### Scenario: Bind an unset tag
- **WHEN** an owner enters the code of a tag that is not yet bound to any account
- **THEN** the tag becomes owned by that account and is listed under My Tags
#### Scenario: Bind an already-owned tag
- **WHEN** an owner enters the code of a tag already bound to another account
- **THEN** the operation is rejected with an error message
### Requirement: List my tags
The account page SHALL list all tags owned by the authenticated owner, with their status and a link to edit each.
#### Scenario: Owner with tags
- **WHEN** an owner opens the account page
- **THEN** all of their tags are shown with status (unset/active) and an edit link
### Requirement: Edit tag details
An owner SHALL be able to set or edit the return details of a tag they own: item type (dog, cat, baggage, skis, other), description, photo URL, phone number, address, and notes.
#### Scenario: Complete tag setup
- **WHEN** an owner fills in all detail fields for a tag and saves
- **THEN** the tag status becomes active and the public page shows the details
#### Scenario: Partial details saved
- **WHEN** an owner saves a tag with only some fields filled
- **THEN** the tag is saved and the public page shows only the filled fields
### Requirement: Remove a tag
An owner SHALL be able to remove a tag from their account. Removing a tag SHALL revert it to the unset state so it can be bound to another account.
#### Scenario: Remove and re-bind
- **WHEN** an owner removes a tag and another account later enters its code
- **THEN** the second account can bind it
### Requirement: Tag ownership limit
An account SHALL be limited to 20 owned tags.
#### Scenario: Limit reached
- **WHEN** an owner who already owns 20 tags tries to bind another tag
- **THEN** the operation is rejected with an error message

View File

@@ -0,0 +1,34 @@
## ADDED Requirements
### Requirement: Account registration
The system SHALL allow a new owner to register with a unique email address and a password. The password SHALL be stored only as a salted hash.
#### Scenario: Successful registration
- **WHEN** a visitor submits a new email and password on the register page
- **THEN** an account is created and the visitor is logged in
#### Scenario: Duplicate email
- **WHEN** a visitor registers with an email that already exists
- **THEN** registration is rejected with an error message
### Requirement: Login and logout
The system SHALL allow an owner to log in with email and password and to log out, maintaining an authenticated session via a signed session cookie.
#### Scenario: Successful login
- **WHEN** an owner submits the correct email and password
- **THEN** a session cookie is set and the owner is authenticated
#### Scenario: Incorrect password
- **WHEN** an owner submits a wrong password
- **THEN** login is rejected with an error message and no session is created
#### Scenario: Logout
- **WHEN** an authenticated owner clicks logout
- **THEN** the session is destroyed and the owner is redirected to the home page
### Requirement: Session-protected routes
Routes that manage tags SHALL require an authenticated session and redirect unauthenticated visitors to the login page.
#### Scenario: Unauthenticated access to account
- **WHEN** a visitor who is not logged in opens the account page
- **THEN** they are redirected to the login page