Skip to content

Commit a620f0f

Browse files
author
AI Assistant
committed
feat: PRD english version
1 parent a1b9a0c commit a620f0f

File tree

2 files changed

+419
-0
lines changed

2 files changed

+419
-0
lines changed

docs/activity-bookings.en.PRD.md

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
ID: 'PRACTICA_ACTIVITY-BOOKINGS'
3+
Course: 'Copilot-CSharp'
4+
Archetype: 'CSharp-API'
5+
Author: 'Students'
6+
---
7+
# PRD — Activity Bookings API
8+
9+
## 1. Executive Summary
10+
11+
REST API to manage bookings for tourist activities. The goal is for students to implement a basic CRUD (Create, Read, Update, Delete), persisting data to files (JSON, CSV, or XML). The solution does not require authentication, third-party services, or a database.
12+
13+
### 1.1 Goals and Metrics
14+
15+
* Build a working REST API with all endpoints functional locally.
16+
* Ensure the application can be run with the command `dotnet run`.
17+
* Implement unit and integration tests to validate API behavior.
18+
19+
### 1.2 Audience
20+
21+
* Students: to gain practical experience.
22+
* Instructors: to use as guidance and to assess learning outcomes.
23+
24+
### 1.3 Technologies
25+
* Language: C# with .NET 9+. [ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-9.0&tabs=visual-studio)
26+
* Libraries: Minimal, preferably only `System.Net.Http` and `System.Text.Json`.
27+
* Tools: Visual Studio Code or Visual Studio with the .NET CLI
28+
* Deployment: Runnable service on localhost using the command `dotnet run`.
29+
30+
## 2. Scope
31+
32+
* Included: REST API with a basic CRUD backed by JSON, CSV, or XML files.
33+
* Excluded: Authentication, payments, notifications, databases.
34+
35+
### 2.1 User Stories
36+
37+
* As a user, I want to list all offered activities.
38+
* As a user, I want to view details of a specific activity.
39+
* As a user, I want to create a new booking for an activity.
40+
* As a user, I want to see all my bookings.
41+
* As a user, I want to cancel an existing booking.
42+
43+
### 2.2 Functional Requirements
44+
45+
1. RF-1: `GET /activities` - List all available activities.
46+
2. RF-2: `GET /activities/{id}` - Show details for a specific activity.
47+
3. RF-3: `POST /bookings` - Create a new booking.
48+
4. RF-4: `GET /bookings` - List all existing bookings.
49+
5. RF-5: `DELETE /bookings/{id}` - Cancel a booking.
50+
51+
### 2.3 Additional Functional Requirements
52+
53+
6. RF-6: `GET /activities/{id}/bookings` - List all bookings for a specific activity.
54+
7. RF-7: `PUT /bookings/{id}` - Update an existing booking.
55+
8. RF-8: `GET /activities?status={status}` - Filter activities by status (e.g. `available`, `finished`).
56+
57+
### 2.4 Non-Functional Requirements
58+
59+
* Simplicity: Prioritize clarity and simplicity in the implementation.
60+
* Design: The API should follow RESTful design with clear, consistent routes.
61+
* Performance: API responses should be fast, preferably under 1 second.
62+
* Persistence: Use JSON, CSV, or XML files for data storage.
63+
* Technologies: Use .NET 9+ and minimal NuGet packages.
64+
65+
## 3. Data Model and Business Rules
66+
67+
### 3.1 Data Schema
68+
69+
* Activity:
70+
71+
* `id` (int)
72+
* `name` (string)
73+
* `price` (float)
74+
* `date` (datetime)
75+
* `status` (string: `available`, `finished`, `cancelled`, `full`)
76+
* `capacity` (optional, int): maximum number of bookings.
77+
* `quorum` (optional, int): minimum number of bookings required for the activity to take place.
78+
79+
* Booking:
80+
81+
* `id` (int)
82+
* `activityId` (int)
83+
* `customerName` (string)
84+
* `bookingDate` (datetime)
85+
* `status` (string: `confirmed`, `cancelled`)
86+
87+
### 3.2 Relationships
88+
89+
* An Activity can have multiple Bookings.
90+
* A Booking belongs to a single Activity.
91+
92+
### 3.3 Business Rules
93+
94+
* Activities with status `finished` or `full` cannot be booked.
95+
* A booking cannot be cancelled if less than 48 hours remain before the activity starts.
96+
* When an activity reaches its `capacity`, its status must change to `full`.
97+
* If the `quorum` is not met 48 hours before the activity, the activity should be cancelled automatically and users notified (simulated with a log message).
98+
99+
## 4. Acceptance Criteria and Risks
100+
101+
### 4.1 Acceptance Criteria
102+
103+
* Each endpoint returns human-readable JSON.
104+
* The API runs without errors.
105+
* Unit and integration tests pass.
106+
* I/O errors (file read/write) are handled properly.
107+
108+
### 4.2 Risks
109+
110+
* File handling errors (reading/writing) could corrupt data.
111+
112+
## 5. Example Data (Seed Data)
113+
114+
### 5.1 Activities
115+
116+
```json
117+
[
118+
{"id":1, "name":"City Tour", "price":50.0, "date":"2026-07-15T10:00:00", "status":"available", "capacity": 10},
119+
{"id":2, "name":"Mountain Hike", "price":80.0, "date":"2026-07-20T08:00:00", "status":"available", "quorum": 5},
120+
{"id":3, "name":"Museum Visit", "price":30.0, "date":"2024-07-18T14:00:00", "status":"finished"}
121+
]
122+
```
123+
124+
```csv
125+
id,name,price,date,status,capacity,quorum
126+
1,City Tour,50.0,2026-07-15T10:00:00,available,10,
127+
2,Mountain Hike,80.0,2026-07-20T08:00:00,available,,5
128+
3,Museum Visit,30.0,2024-07-18T14:00:00,finished,,
129+
```
130+
131+
```xml
132+
<activities>
133+
<activity>
134+
<id>1</id>
135+
<name>City Tour</name>
136+
<price>50.0</price>
137+
<date>2026-07-15T10:00:00</date>
138+
<status>available</status>
139+
<capacity>10</capacity>
140+
</activity>
141+
<activity>
142+
<id>2</id>
143+
<name>Mountain Hike</name>
144+
<price>80.0</price>
145+
<date>2026-07-20T08:00:00</date>
146+
<status>available</status>
147+
<quorum>5</quorum>
148+
</activity>
149+
<activity>
150+
<id>3</id>
151+
<name>Museum Visit</name>
152+
<price>30.0</price>
153+
<date>2024-07-18T14:00:00</date>
154+
<status>finished</status>
155+
</activity>
156+
</activities>
157+
```
158+
159+
### 5.2 Bookings
160+
161+
```json
162+
[
163+
{"id":1, "activityId":1, "customerName":"Juan Pérez", "bookingDate":"2025-06-01T12:00:00", "status":"confirmed"},
164+
{"id":2, "activityId":2, "customerName":"María Gómez", "bookingDate":"2025-06-02T15:30:00", "status":"confirmed"},
165+
{"id":3, "activityId":1, "customerName":"Luis Martínez", "bookingDate":"2025-06-03T09:45:00", "status":"cancelled"}
166+
]
167+
```
168+
169+
```csv
170+
id,activityId,customerName,bookingDate,status
171+
1,1,Juan Pérez,2025-06-01T12:00:00,confirmed
172+
2,2,María Gómez,2025-06-02T15:30:00,confirmed
173+
3,1,Luis Martínez,2025-06-03T09:45:00,cancelled
174+
```
175+
176+
```xml
177+
<bookings>
178+
<booking>
179+
<id>1</id>
180+
<activityId>1</activityId>
181+
<customerName>Juan Pérez</customerName>
182+
<bookingDate>2025-06-01T12:00:00</bookingDate>
183+
<status>confirmed</status>
184+
</booking>
185+
<booking>
186+
<id>2</id>
187+
<activityId>2</activityId>
188+
<customerName>María Gómez</customerName>
189+
<bookingDate>2025-06-02T15:30:00</bookingDate>
190+
<status>confirmed</status>
191+
</booking>
192+
<booking>
193+
<id>3</id>
194+
<activityId>1</activityId>
195+
<customerName>Luis Martínez</customerName>
196+
<bookingDate>2025-06-03T09:45:00</bookingDate>
197+
<status>cancelled</status>
198+
</booking>
199+
</bookings>
200+
```

0 commit comments

Comments
 (0)