About the project
The list and detail pages used mismatched API contracts. Fields, pagination and validation needed to be aligned, with visitor records separated for the demo.
Catalogue, listing details and a creation form. Vue calls a Laravel API on the same origin. Sorting, pagination and validation are included. Visitor records are separated by session.
- All listings and images are for demonstration. Sales and arbitrary uploads are disabled.
- 20 personal listings per session, 1,000 in total; one-hour TTL and a cleanup timer every five minutes.
- The legacy Vue build tooling has known development-dependency issues; a full frontend tooling migration was not performed.
Screenshots, diagrams and source evidence retain their original language; captions and descriptions are translated.
Architecture and diagrams
- The client and API share one origin with no external backend URL.
- The 24 seed listings are shared; visitor-created records are filtered by owner.
- Images come from a fixed set of local SVGs; arbitrary URLs and mass assignment are excluded.
- Prices are stored as DECIMAL(10,2); the API returns consistent scalar pagination metadata.
Code map: files and dependencies
This map is tied to version 54f1be9aa105. The table lists the screen or API, related module and data.
| Feature | Screen / API | Module | Data / verification |
|---|---|---|---|
| Catalog, search and sorting | AdList / GET api/ad | AdController::index | ads, owner scope |
| Details | AdItem / GET api/ad/id | AdController::show | seed or own record |
| Creation | AdNew / POST api/ad | Validator, Eloquent | allowlist + session_id + expires_at |
| Deletion and reset | AdItem / DELETE, POST demo/reset | AdController, DemoSession | own session only |
| Cleanup | CLI demo:cleanup | scheduled command | expired rows |
Using the code map
- Before making a change, find the feature and trace its links to the API, state and storage.
- Check inputs, errors, repeated events and dependent workflows.
- After making a change, update the map and affected diagrams alongside the code.
- Run the related checks and link the new evidence to the source version.
Workflows and API
- Open the catalog, change sorting and go to the next page.
- View listing details and create a listing using a local image.
- Check validation of empty or invalid input.
- Open another visitor's ID in a second session: expect 404. Delete your own listing and reset the example.
Verification of the published version
CI: Vue: production build for /catalog/ ↗ · ba775c53 · historical run of a different version · 2026-09-07
- Full production QA repeated at /catalog/: create, delete, search, sort, pagination, sessions and mobile view — passed. The page opens in the original Chrome session with the ad blocker enabled.
- Sorting, pagination, search, empty state
- Required form validation
- Signed Secure HttpOnly cookie; cross-session GET/DELETE both 404
- Server rejects negative price, short text and external image URL
- Cancel, delete and restored seed count
- No verified GitHub CI run is available for this SHA; the listed evidence covers local checks and published-version scenarios. Historical CI links, where available, are labeled separately.
These checks apply to the listed version. Business metrics and model quality on an independent dataset were not measured.
Measurements
- 13 meaningful screenshots of the actual interface retained.
- Each screenshot includes its date, scenario and code revision.
- Peak container RAM in the short test: 39.76 MiB. Shared services are counted separately; the shop includes its own database.
- 6 scenario repetitions measured; median 1605.5 ms, maximum 2981 ms. Timing includes the browser and HTTPS; methodology and limitations are included.
Running and operating
Update, 7 September 2026: the frontend is published at /catalog/ on the main domain. The old ads subdomain redirects here because a browser ad blocker blocked its JS/CSS. The Laravel backend is unchanged.
This case combines laravel-sandbox and laravel-sandbox-ui. It is one project with two repositories; both SHAs are retained in release metadata.
Builds run outside the VPS using Dockerfile.portfolio and a separate ads-ui build context. composer.lock and package-lock.json pin dependency versions.
Nginx → localhost:18402 → Apache/Laravel. The ads database and user are separate. Check /healthz, GET /api/ad, POST /api/ad and read/delete for your own ID. A system timer runs php artisan demo:cleanup; reset does not delete seed data or other visitors' records.
Builds run outside the VPS; the server receives static files and versioned images. Secrets are kept separately. Logs rotate; changing log options requires recreating the container. No server-wide docker prune.
The code map links a screen or API to its module and data. A change needs those links checked, the map updated and the affected flows rerun: normal path, error, retry and reset. Diagrams can go stale, so their version is listed alongside them.
Rollback checked at 2026-09-07T01:00:33.586236+00:00: 20260907-verified → 20260907b → 20260907-verified. HTTPS, readiness and SHA were confirmed after each switch. This checks configuration and artifacts at one verified SHA; no reverse database migration was performed.
Stack
| Laravel / Eloquent | Validation, owner scope, CRUD and expiration. |
|---|---|
| Vue | Catalog routes, listing details, forms, sorting and pagination. |
| MySQL | Listings, DECIMAL prices and retention period. |
Materials and source code
Vue: catalog and forms ↗ · version ba775c53a6b3
Backend and Vue client: April 2024. Public demo update: 7 September 2026.
The evidence archive retains its original language.