ramadanproject/specs/001-public-grid-viewer/spec.md
Ahmed Darrazi 45a147253c
Some checks failed
tests / ci (push) Failing after 6m13s
linter / quality (pull_request) Failing after 58s
linter / quality (push) Failing after 1m19s
tests / ci (pull_request) Failing after 5m28s
feat(public-grid): add QA, quickstart, decision docs; scheduler docs; ignore files; tasks updates; run pint
2026-01-03 04:56:12 +01:00

174 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Feature Specification: Public Grid Viewer + Live Selection (Vertical Slice)
**Feature Branch**: `001-public-grid-viewer`
**Created**: 2026-01-03
**Status**: Draft
**Input**: User description: "Feature 1: Public Grid Viewer + Live Selection (no checkout). Vertical slice: public master image + pan/zoom + canvas-based grid, selection, server-side price prop, stub availability, upload preview modal (no payment)."
## Constitution Alignment (REQUIRED)
This spec MUST comply with `constitution.md`. If not, document deviation + mitigation here.
### Mandatory Invariants
- [ ] Server computes price; client is display-only
- [ ] DB-level prevention of double booking
- [ ] Webhooks + rendering pipeline are idempotent
- [ ] Rendering occurs in queued job(s)
## Success Criteria (MUST)
Define measurable outcomes for "done".
- Performance:
- [ ] Public page loads master image + metadata within ___ ms on ___ connection
- Correctness:
- [ ] No double booking possible under concurrency
- [ ] Paid orders render exactly once (idempotent)
- UX:
- [ ] User can select cells, preview, and pay end-to-end
- Security:
- [ ] Upload rules enforced (type/size/dimensions), safe link validation
## Acceptance Scenarios (MUST)
Write at least 3 end-to-end scenarios (Gherkin-style preferred).
### Scenario 1: Reserve → Pay → Render
Given the public page is loaded with the master image and grid
When a visitor drags a rectangular selection over the grid and opens the sidebar
Then the UI shows the selected cell count and the server-provided `price_per_cell` and computes the total price (display only)
### Scenario 2: Concurrent selection conflict
Given two visitors load the same public page
When Visitor A selects a block of cells and Visitor B selects an overlapping block
Then both visitors see availability overlays; selection is local (no booking) and the server availability API reports occupied cells when present (MVP: API returns empty set)
### Scenario 3: Webhook replay / retry
Given this vertical slice does not include payment, webhook scenarios are out of scope for this feature; the spec requires the pipeline to be prepared for idempotent webhooks in later features.
## Scope (See <attachments> above for file contents. You may not need to search or read the file again.)
This vertical slice covers the public-facing viewer and live selection experience without creating orders or processing payments. It provides the UI and server endpoints required to compute prices, return current `master_version`, and (MVP) return an availability stub. It does NOT: create reservations in the database, process payments, run rendering Jobs, or persist uploaded images permanently.
## User Scenarios & Testing *(mandatory)*
<!--
IMPORTANT: User stories should be PRIORITIZED as user journeys ordered by importance.
Each user story/journey must be INDEPENDENTLY TESTABLE - meaning if you implement just ONE of them,
you should still have a viable MVP (Minimum Viable Product) that delivers value.
Assign priorities (P1, P2, P3, etc.) to each story, where P1 is the most critical.
Think of each story as a standalone slice of functionality that can be:
- Developed independently
- Tested independently
- Deployed independently
- Demonstrated to users independently
-->
### User Story 1 - Public viewer + Live selection (Priority: P1)
Any visitor can open the public grid page, pan/zoom the master image, draw a rectangular selection (multi-cell), and see the live cell count and computed total price. The selection is client-only for now; no reservation or checkout is created.
**Why this priority**: Validates UI complexity (grid, pan/zoom, selection) early and delivers immediate visible value.
**Independent Test**: Load the public page, perform selection on desktop and mobile, verify cell count and price calculation match server-provided `price_per_cell`.
**Acceptance Scenarios**:
1. **Given** the public master image is visible, **When** the user drags to select cells, **Then** the sidebar updates with cell count and total price.
2. **Given** mobile device, **When** user pinches/drag to select, **Then** selection precision is maintained and preview shows correctly.
---
### User Story 2 - Upload preview modal (Priority: P2)
User can open a modal from the sidebar, select an image file and optional link, and see a client-side preview composited into the selection rectangle. The modal does not persist anything to the server in this slice.
**Independent Test**: Select an image and link, verify preview scales/crops to selection proportion and displays correctly.
---
### User Story 3 - Availability overlay (Priority: P3)
Server exposes a lightweight endpoint returning currently occupied cell coordinates. For the vertical slice this may return an empty list (stub) but the client must render any occupied cells in a distinct overlay.
**Independent Test**: Call the availability endpoint and verify the overlay marks returned coordinates as unavailable.
---
[Add more user stories as needed, each with an assigned priority]
### Edge Cases
- Selection partially outside bounds: selection is clamped to image bounds and cell counts reflect clamped area.
- Very large selection on mobile: UI prevents selections beyond a maximum configured cell count and shows a warning.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: Public page MUST return `master_image_url` and `master_version`.
- **FR-002**: Client MUST be able to request `price_per_cell` from the server; client computes `cell_count × price_per_cell` for display only.
- **FR-003**: Client MUST render an interactive grid overlay and allow rectangle selection with pan/zoom support.
- **FR-004**: Client MUST provide an upload + link modal with client-side preview scaled to selection.
- **FR-005**: Server MUST expose an availability endpoint returning occupied cells (MVP: can return empty set).
- **FR-006**: All endpoints MUST validate inputs and rate-limit sensitive endpoints.
### Key Entities *(include if feature involves data)*
- **MasterImage**: `path`, `version` (for cache-busting)
- **Availability**: list of `{cell_x, cell_y}` entries returned by endpoint
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: Public page loads master image and metadata within 2000ms on a 4G connection (approximate).
- **SC-002**: Selection cell coordinates reported by client match server cell unit grid (pixel-accurate within 1 cell).
- **SC-003**: Mobile pinch/drag interaction completes selection without lost events on iPhone 14 Pro viewport.
- **SC-004**: Price calculation displays correctly using server-provided `price_per_cell`.
## Assumptions
- `cell_size` (in pixels) is a server-configured value provided to the client.
- Availability API may return empty set for MVP; production will enforce DB-level locks later.
## Out of Scope
- Creating orders, reservations, payments, rendering jobs, or persisting uploaded images.
## Requirements *(mandatory)*
<!--
ACTION REQUIRED: The content in this section represents placeholders.
Fill them out with the right functional requirements.
-->
### Functional Requirements
- **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"]
- **FR-002**: System MUST [specific capability, e.g., "validate email addresses"]
- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"]
- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"]
- **FR-005**: System MUST [behavior, e.g., "log all security events"]
*Example of marking unclear requirements:*
- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?]
- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified]
### Key Entities *(include if feature involves data)*
- **[Entity 1]**: [What it represents, key attributes without implementation]
- **[Entity 2]**: [What it represents, relationships to other entities]
## Success Criteria *(mandatory)*
<!--
ACTION REQUIRED: Define measurable success criteria.
These must be technology-agnostic and measurable.
-->
### Measurable Outcomes
- **SC-001**: [Measurable metric, e.g., "Users can complete account creation in under 2 minutes"]
- **SC-002**: [Measurable metric, e.g., "System handles 1000 concurrent users without degradation"]
- **SC-003**: [User satisfaction metric, e.g., "90% of users successfully complete primary task on first attempt"]
- **SC-004**: [Business metric, e.g., "Reduce support tickets related to [X] by 50%"]