Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
/node_modules
npm-debug.log
yarn-error.log
pnpm-debug.log
.env
.env.*

# IDEs and editors
.idea/
Expand Down
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
*.scss
node_modules/
dist/
build/
coverage/
package-lock.json
yarn.lock
pnpm-lock.yaml
15 changes: 0 additions & 15 deletions docs/staff-dashboard-improvements.md

This file was deleted.

32 changes: 30 additions & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@ const angular = require('angular-eslint');
module.exports = tseslint.config(
{
files: ['**/*.ts'],
ignores: ['**/*.spec.ts', 'node_modules/**', 'src/contract/**'],
ignores: [
'**/*.spec.ts',
'**/*.min.js',
'node_modules/**',
'src/contract/**',
'dist/**',
'build/**',
'out/**',
'coverage/**',
'.angular/cache/**',
'.bazel/**',
'public/**',
'docs/**',
'pnpm-lock.yaml',
],
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
Expand Down Expand Up @@ -35,7 +49,21 @@ module.exports = tseslint.config(
},
{
files: ['**/*.html'],
ignores: ['**/*.spec.ts', 'node_modules/**', 'src/contract/**'],
ignores: [
'**/*.spec.ts',
'**/*.min.js',
'node_modules/**',
'src/contract/**',
'dist/**',
'build/**',
'out/**',
'coverage/**',
'.angular/cache/**',
'.bazel/**',
'public/**',
'docs/**',
'pnpm-lock.yaml',
],
extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility],
rules: {},
},
Expand Down
34 changes: 34 additions & 0 deletions specs/001-staff-booking-flow/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Specification Quality Checklist: Staff Booking Fulfillment Workspace

**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2025-11-12
**Feature**: [Link to spec.md](../spec.md)

## Content Quality

- [x] No implementation details (languages, frameworks, APIs)
- [x] Centered on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified

## Feature Readiness

- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification

## Notes

- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan`
17 changes: 17 additions & 0 deletions specs/001-staff-booking-flow/checklists/us1-booking-entry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# User Story 1 – Booking Fulfillment Entry Validation

## Manual QA Walkthrough

- [ ] Launch local app with `pnpm start` and authenticate as staff user
- [ ] From `Bookings` dashboard, select an approved booking and open fulfillment route
- [ ] Confirm document title updates to "Xử lý đặt xe" (or localized equivalent)
- [ ] Check booking summary shows renter profile, vehicle, and booking metadata
- [ ] Validate fulfillment checklist locks steps other than check-in before completion
- [ ] Trigger check-in action and observe optimistic progress indicator
- [ ] Confirm success toast/banner copy and timeline entry appear after check-in
- [ ] Refresh browser tab; verify fulfillment state, timeline, and checklist persist
- [ ] Exercise error path by forcing API failure (mock/network) and confirm retry affordance

## Evidence Log

- Notes: <!-- tester notes -->
16 changes: 16 additions & 0 deletions specs/001-staff-booking-flow/checklists/us2-rental-package.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# User Story 2 – Rental Package Preparation

## Manual QA Walkthrough

- [ ] From the fulfillment page, verify only the rental creation step is actionable after check-in
- [ ] Trigger rental creation and confirm success toast or timeline entry exposes the new `rentalId`
- [ ] Proceed to contract issuance, choose an e-sign provider, and confirm the `contractId` appears in the summary metadata
- [ ] Attempt to re-run contract issuance and ensure the UI prevents duplicate submissions while busy
- [ ] Complete the inspection form with battery level, timestamp, and evidence URL; verify optimistic status change and persisted inspection reference
- [ ] Refresh the page and validate rental, contract, and inspection artifacts remain visible with fulfilled badges
- [ ] Force an API failure on inspection submission and confirm error messaging plus retry affordance
- [ ] Confirm the next actionable step advances to renter signing after inspection success

## Evidence Log

- Notes: <!-- tester notes -->
16 changes: 16 additions & 0 deletions specs/001-staff-booking-flow/checklists/us3-finalization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# User Story 3 – Finalize Contract & Vehicle Handover

## Manual QA Walkthrough

- [ ] Continue from a fulfilled inspection and verify renter signature step becomes actionable
- [ ] Submit renter signature details and confirm signature ID surfaces in the checklist and summary
- [ ] Attempt double submission of renter signature while busy to confirm duplicate prevention
- [ ] Complete staff signature using a different signature type and ensure both signatures display distinct metadata
- [ ] Inspect the activity timeline to verify renter and staff signature events include actor labels and timestamps
- [ ] Capture vehicle receive time and confirm staff identifier appears in both checklist artifact chips and summary cards
- [ ] Refresh the browser and validate all finalization steps remain fulfilled with artifacts intact
- [ ] Force a failure on vehicle receive API and confirm error state with retry button restores actionable status

## Evidence Log

- Notes: <!-- tester notes -->
147 changes: 147 additions & 0 deletions specs/001-staff-booking-flow/contracts/booking-fulfillment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
openapi: 3.0.3
info:
title: EV Rental Frontend Booking Fulfillment Orchestration
version: 1.0.0
description: >-
Logical contract map for required backend calls triggered by the staff booking
fulfillment UI. Mirrors existing EV Rental REST API endpoints consumed via
generated OpenAPI clients.
servers:
- url: https://api.ev-rental.local
paths:
/api/Booking/checkin:
post:
summary: Staff confirms booking check-in
operationId: staffCheckinBooking
tags:
- Booking
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CheckinBookingRequest'
responses:
'200':
description: Booking check-in processed successfully
content:
application/json:
schema:
$ref: '#/components/schemas/BookingApiResponse'
/api/Rental:
post:
summary: Create rental for approved booking
operationId: staffCreateRental
tags:
- Rental
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateRentalRequest'
responses:
'200':
description: Rental created
content:
application/json:
schema:
$ref: '#/components/schemas/RentalApiResponse'
/api/Rental/contract:
post:
summary: Generate contract for rental
operationId: staffCreateRentalContract
tags:
- Rental
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateContractRequest'
responses:
'200':
description: Contract created
content:
application/json:
schema:
$ref: '#/components/schemas/ContractApiResponse'
/api/Rental/inspection:
post:
summary: Record pre-handover inspection
operationId: staffRecordInspection
tags:
- Rental
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ReceiveInspectionRequest'
responses:
'200':
description: Inspection stored
content:
application/json:
schema:
$ref: '#/components/schemas/InspectionApiResponse'
/api/Rental/contract/sign:
post:
summary: Capture digital signature
operationId: staffSignContract
tags:
- Rental
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SignContractRequest'
responses:
'200':
description: Signature stored
content:
application/json:
schema:
$ref: '#/components/schemas/ContractApiResponse'
/api/Rental/vehicle/receive:
post:
summary: Confirm vehicle handover
operationId: staffReceiveVehicle
tags:
- Rental
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ReceiveVehicleRequest'
responses:
'204':
description: Vehicle receive acknowledged
components:
schemas:
CheckinBookingRequest:
$ref: '../../src/contract/model/checkinBookingRequest.ts'
CreateRentalRequest:
$ref: '../../src/contract/model/createRentalRequest.ts'
CreateContractRequest:
$ref: '../../src/contract/model/createContractRequest.ts'
ReceiveInspectionRequest:
$ref: '../../src/contract/model/receiveInspectionRequest.ts'
SignContractRequest:
$ref: '../../src/contract/model/signContractRequest.ts'
ReceiveVehicleRequest:
$ref: '../../src/contract/model/receiveVehicleRequest.ts'
BookingApiResponse:
description: Wraps booking details payload (placeholder for generated model)
type: object
RentalApiResponse:
description: Wraps rental details payload (placeholder for generated model)
type: object
ContractApiResponse:
description: Wraps contract details payload (placeholder for generated model)
type: object
InspectionApiResponse:
description: Wraps inspection details payload (placeholder for generated model)
type: object
Loading