openspec: frontend-foundation change — proposal, design, specs (4 capabilities), tasks
This commit is contained in:
33
openspec/changes/frontend-foundation/specs/database/spec.md
Normal file
33
openspec/changes/frontend-foundation/specs/database/spec.md
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
34
openspec/changes/frontend-foundation/specs/user-auth/spec.md
Normal file
34
openspec/changes/frontend-foundation/specs/user-auth/spec.md
Normal 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
|
||||
Reference in New Issue
Block a user