eCommerce web system with full backoffice: a Spring Boot 4 REST API with JPA, BCrypt password hashing, and token auth, an Angular 22 storefront with an admin console, and MySQL 9.7 LTS storage. v3 adds server-priced orders with an atomic stock guard, HMAC-signed payment sessions, coupons, wishlists, and sales reports. For a simpler legacy architecture, check v2.0.
- Pictures
- Local development
- Production environment setup
- QA harness
- Build logs
- Architecture and flows
The v3 user journey first, then the admin console. Regenerate the set against the current build with make screenshots.
- Guest shop page

- Product details

- Guest shopping cart

- Checkout with a coupon applied

- Payment gateway page

- Member account details

- Order history with cancel while pending

- Wishlist

- Not-found page

- Admin dashboard with the sales report

- Admin products listing

- Admin create new product

- Admin edit product

- Admin batch delete

- Admin import products from Excel

- Admin export products to Excel

- Admin orders with the status filter

- Admin coupons

- Admin branch stock editor

Shot 17 keeps its legacy filename 05-admin-transaction-summary.png, the v3 capture regenerated it as the admin orders screen.
Prerequisites: JDK 27, Docker, make, and Node 24 with npm on PATH. CURL or Postman helps for ad hoc API calls, and any editor works. The Maven wrapper and make targets wrap every build, test, and run step, and the build provisions its own Node 24 for the Angular bundle.
-
Start MySQL and seed it:
make db-upthenmake db-seed, ormake db-resetto drop the volume and redo both in one step. The seed writes the schema, 4 demo users, the taxonomy, 79 products, 6 Ho Chi Minh City branches with stock rows, and 3 coupons (WELCOME10percent,SHIP50Kfixed,EXPIRED5inactive). -
Build and run:
make packageruns the full clean build with tests, thenmake runstarts the newesttarget/flowershop-*.jaragainst the compose MySQL and serves the built SPA. The Makefile exports theLOCAL_MYSQL_DB_*variables matching compose, so noapplication.ymledit is needed unless you run your own MySQL. -
Log in over JSON as the seeded admin (password
1234qwer):curl -s -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email": "[email protected]", "password": "1234qwer"}'
The 200 body is
{"token": "...", "user": {user}}. Tokens are minted by login, rotated on every fresh login, and die on logout or restart, since sessions live in memory. -
Send the token in the
X-Auth-Tokenheader on every authenticated call:curl -s http://localhost:8080/api/user/me -H "X-Auth-Token: <token>"The whole contract, including the error code list and the payment signature scheme, is frozen in docs/api-v3.md.
-
For frontend work:
make frontend-installthenmake frontend-serveserves the dev build athttp://localhost:4200, proxying/apito:8080.
- The host needs
JDK 27andMySQL Server 9.7 LTS. Set up the database andapplication.ymlas in development. - Run
make packagefrom the root folder. This createstarget/flowershop-3.0.jar. - Run the jar with
java -jar target/flowershop-3.0.jar. - On AWS: an EC2 instance or a Lightsail VPS runs the jar, RDS serves MySQL 9.7, and S3 holds backups and static assets.
Every gate runs through a make target, and the committed reports under docs/qa/ hold the numbers below.
make backend-test:mvn verifywith a JaCoCo bundle gate at 0.90 covered ratio on lines and instructions, plus the concurrency suites for oversell, payment replay, and signature tamper.make test-coverage: the vitest suite with thresholds at 90 percent on statements, branches, functions, and lines.make fuzz: boots the packaged jar on a scratch port and fires the committed corpus plus seeded generated variants at every endpoint, asserting documented statuses only, problem+json with contract codes on errors, and zero 5xx, hangs, or run-budget breaches. Baseline run: 350 requests over 54 endpoint templates, zero assertion failures, seed 20261007. Report: docs/qa/fuzz-report.md.make mutate: source-level mutation harness sweeping 23 operators over the logic-dense backend classes, one mutant per run against its mapped test classes, tree restored and verified between runs. Baseline run over 17 targets: 192 mutants, 188 killed by failing tests, 4 by compile rejection, 0 by timeout, 0 survivors. Report: docs/qa/mutation-report.md.make mutate-front: the same conventions over the TypeScript core and services classes with 19 operators. Baseline run: 93 mutants, 71 killed by failing specs, 22 by compile rejection, 0 by timeout, 0 survivors. Report: docs/qa/mutation-front-report.md.- CI runs four gate jobs on every push and pull request: backend tests and the API fuzz gate, both against a MySQL 9.7.2 service container on JDK 27, frontend lint, coverage, and build on Node 24, and the npm audit zero-vulnerability gate. A badges job needs all four and publishes the ci and coverage badges above from master pushes, uploading the fuzz report and server log when the fuzz gate fails.
Both mutation runs open with an unmutated control pass over the mapped tests and abort when it comes back red, refuse to start on a dirty source tree, restore and verify every mutant with git before the next, and run only the mapped test classes per target. The maps pin line numbers, so any line shift in a mapped file needs a map recalibration. The fuzz harness derives deterministic HMAC-tagged credentials per run, keyed on the run tag, and truncates its server log per run.
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ flowershop ---
[INFO] Building jar: /home/lavantien/Documents/dev/flowershop/target/flowershop-1.1.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.3.2.RELEASE:repackage (repackage) @ flowershop ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 44.918 s
[INFO] Finished at: 2020-08-07T00:57:12+07:00
[INFO] ------------------------------------------------------------------------
[INFO] Results:
[INFO]
[INFO] Tests run: 119, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- jar:3.5.1:jar (default-jar) @ flowershop ---
[INFO] Building jar: C:\Users\lavantien\dev\github\FlowerShop\target\flowershop-2.0.jar
[INFO]
[INFO] --- spring-boot:4.1.1:repackage (repackage) @ flowershop ---
[INFO] Replacing main artifact C:\Users\lavantien\dev\github\FlowerShop\target\flowershop-2.0.jar with repackaged archive, adding nested dependencies in BOOT-INF/.
[INFO] The original artifact has been renamed to C:\Users\lavantien\dev\github\FlowerShop\target\flowershop-2.0.jar.original
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 35.854 s
[INFO] Finished at: 2026-10-07T10:51:45+07:00
[INFO] ------------------------------------------------------------------------
[INFO] Results:
[INFO]
[INFO] Tests run: 351, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- jar:3.5.1:jar (default-jar) @ flowershop ---
[INFO] Building jar: C:\Users\lavantien\dev\github\FlowerShop\target\flowershop-3.0.jar
[INFO]
[INFO] --- spring-boot:4.1.1:repackage (repackage) @ flowershop ---
[INFO] Replacing main artifact C:\Users\lavantien\dev\github\FlowerShop\target\flowershop-3.0.jar with repackaged archive, adding nested dependencies in BOOT-INF/.
[INFO] The original artifact has been renamed to C:\Users\lavantien\dev\github\FlowerShop\target\flowershop-3.0.jar.original
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 58.556 s
[INFO] Finished at: 2026-10-08T01:11:01+07:00
[INFO] ------------------------------------------------------------------------
Expand for the 4 structural graphs and 14 sequence diagrams
System overview, the whole stack at a glance:
Backend component graph, the controller, service, and repository layering with the token interceptor:
Frontend component graph, the shell, routed feature areas, core services, and guards:
Data model graph, the JPA entities with order, payment session, stock, coupon, and wishlist:
Login and logout, token mint and burn:
Register and password reset:
Browse and catalog query, paging, filters, and the sort whitelist:
Add to cart, the persisted client cart:
Checkout with payment confirm, server-side pricing, the stock guard, and the signed gateway redirect:
Payment cancel, order cancellation and stock restore:
User order cancel while pending:
Admin fulfillment transitions across order statuses:
Coupon lifecycle, create, validate, and checkout integration:
Wishlist toggle:
User admin, listing, edits, and the delete guard:
Excel import and export of the catalog:
Stock and branch admin:
Dashboard report, the sales aggregates:
Regenerate the PNG files from the committed PlantUML sources with make diagrams.

















