About the project
Public deployment required correcting base URLs, frontend/backend contracts and form validation, while preventing one visitor from changing another visitor’s data.
A Laravel API and Vue client implement an ads catalog: list, detail, create, delete, search, sort and pagination. Response and error contracts match across layers; demo CRUD is session-isolated and API plus images use the same origin.
What sets the implementation apart
One contract supports desktop and mobile views, server pagination and validation errors. A session owns its created ads, foreign records return 404, and reset restores the initial dataset without an admin step.
Application-code composition
Shares use Git application-file bytes at pinned revisions. Each file belongs to one subsystem under scripts/generate-stack-share.mjs rules; tests, assets, dependencies and generated files are excluded. Rounded to 0.1%. This describes code composition, not proficiency.
- 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.