Skip to content

Commit 9b7776d

Browse files
Add comprehensive user and project documentation with details on architecture, workflows, and best practices
1 parent 21205ee commit 9b7776d

File tree

2 files changed

+394
-0
lines changed

2 files changed

+394
-0
lines changed

Docs/Projects.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# Sparkly Server – Projects Module
2+
3+
This is the official-but-not-too-serious guide to how Projects work inside Sparkly Server. If Users are the people at the party, Projects are the things they brag about. The Projects module keeps track of them, validates them, and makes sure two people do not name their projects "My Cool App" at the same time.
4+
5+
## What a Project Is
6+
7+
In Sparkly, a Project represents something a user is building or showcasing. The domain model is clean and focused:
8+
9+
• Id – primary key.
10+
11+
• ProjectName – required, unique across all users.
12+
13+
• Description – optional but encouraged.
14+
15+
• Visibility – controls who can see it (public or private).
16+
17+
• OwnerId – reference to the user who created it.
18+
19+
• Owner – navigation property.
20+
21+
• CreatedAt / UpdatedAt – timestamps.
22+
23+
>The entity stays focused on representing state, not performing logic.
24+
25+
## EF Core Mapping
26+
27+
Project mapping in `AppDbContext` ensures:
28+
29+
• Projects live in the `projects` table.
30+
31+
• ProjectName is required and has a max length.
32+
33+
• A unique index on ProjectName.
34+
35+
• A relationship to the User who owns the project.
36+
37+
>This prevents naming collisions and keeps database constraints honest.
38+
39+
## Project Repository
40+
41+
The repository handles all data access for projects. It shields the service layer from EF Core details.
42+
43+
Typical repository operations include (more will be added later):
44+
45+
• Creating a project.
46+
47+
• Fetching by Id.
48+
49+
• Checking if a project name is already taken.
50+
51+
• Fetching all projects for a given user.
52+
53+
• Deleting a project.
54+
55+
>By keeping EF logic here, the rest of the codebase stays clean.
56+
57+
## ProjectService – The Rules and Workflow
58+
59+
The service orchestrates the entire lifecycle of Projects. It contains rules such as:
60+
61+
• Only authenticated users can create projects.
62+
• Project names must be unique.
63+
• The owner must exist.
64+
• Deleting a project should respect authorization.
65+
66+
A typical create workflow looks like:
67+
68+
1. Resolve current user using `ICurrentUser`.
69+
2. Fetch the user from the database.
70+
3. Check if the name is free using `IsProjectNameTakenAsync`.
71+
4. Create a new Project object.
72+
5. Save it through the repository.
73+
74+
When deleting:
75+
76+
• The service confirms ownership.
77+
• Uses EF Core `ExecuteDeleteAsync` for efficient removal.
78+
79+
## Visibility
80+
81+
The visibility field controls who can see the project:
82+
83+
• Public – visible to everyone.
84+
85+
• Private – visible only to the owner and collaborators (coming soon).
86+
87+
>Great for early work-in-progress projects or things that should not be judged yet.
88+
89+
## DTOs for Projects
90+
91+
DTOs ensure only safe and selected data leaves the server:
92+
93+
• CreateProjectDto – incoming data when creating.
94+
95+
• ProjectDto – returned when fetching.
96+
97+
• Delete or Update DTOs, if needed.
98+
99+
>They make API responses predictable and consistent.
100+
101+
## Controllers – The HTTP Face of Projects
102+
103+
Endpoints related to projects include:
104+
105+
• POST /projects – create a new project.
106+
107+
• GET /projects/{id} – fetch project by id.
108+
109+
• GET /projects – fetch user’s projects.
110+
111+
• DELETE /projects/{id} – remove a project.
112+
113+
>Controllers stay thin. They accept input, send it to the service, and return the result.
114+
115+
## Authorization
116+
117+
All project routes require authentication. Creating or deleting requires you to be the owner. The system uses `ICurrentUser` injected via DI to know who is making the request.
118+
119+
Typical rule:
120+
121+
If you made it, you can delete it. If you did not, hands off.
122+
123+
## Data Validation
124+
125+
Project creation validates:
126+
127+
• Name not empty.
128+
129+
• Name length within limits.
130+
131+
• Name not already taken.
132+
133+
This avoids duplicates and cleans up common user mistakes.
134+
135+
## Clean Architecture Layout
136+
137+
The module respects the structure:
138+
139+
Domain → Repository → Service → Controller.
140+
141+
>Nothing leaks across layers. No EF in controllers. No HTTP in domain. No shortcuts.
142+
143+
## Summary
144+
145+
The Projects module ensures that Sparkly has a clean, organized list of user creations. It enforces uniqueness, ownership, and visibility rules without slowing the developer down.
146+
147+
You can extend this module later with features such as:
148+
149+
• Tags.
150+
151+
• Slugs.
152+
153+
• Project collaborators.
154+
155+
• Project statistics.
156+
157+
• Version history.
158+
159+
All the foundation is ready. Sparkly is flexible enough to grow as fast as your ideas do.

Docs/Users.md

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# Sparkly Server – Users & Authentication
2+
3+
This document is the slightly chaotic but fully functional guide to how Sparkly Server handles Users and Authentication. If Sparkly were a nightclub, this module would manage the guest list, check IDs, validate wristbands, and occasionally throw someone out when their token expires.
4+
5+
## What a User Is in Sparkly
6+
7+
A User is a simple creature. The domain model represents only what matters:
8+
9+
• Id – primary key, a GUID with attitude.
10+
11+
• Email – unique, required, cannot be nonsense.
12+
13+
• UserName – the name that appears publicly.
14+
15+
• PasswordHash – the encrypted version of whatever password the user typed.
16+
17+
• Projects – navigation to the projects the user owns.
18+
19+
>The entity carries no business logic. It is deliberately boring. That is good.
20+
21+
## Persistence: EF Core Mapping
22+
23+
Users are mapped inside `AppDbContext` to a clean `users` table. The key details:
24+
25+
• Email has a unique index.
26+
27+
• All required fields are enforced.
28+
29+
• Relationship between User → Projects is defined, so ownership is always clear.
30+
31+
>EF Core takes care of the SQL, so you never have to think about migrations while half‑asleep.
32+
33+
## User Repository – Access Without Drama
34+
35+
The repository provides controlled access to the database. It typically allows:
36+
37+
• Finding users by Id.
38+
39+
• Finding users by Email.
40+
41+
• Creating new users.
42+
43+
• Checking email uniqueness.
44+
45+
>The repository keeps the rest of the app blissfully unaware of how the database works.
46+
47+
## Authentication: The Sparkly Way
48+
49+
Sparkly uses JWTs. Nothing exotic. Just clean, industry‑standard authentication.
50+
51+
The flow is straightforward:
52+
53+
1. A user sends credentials.
54+
2. The service checks email and password.
55+
3. If valid, Sparkly issues two tokens:
56+
57+
• Access Token – short lived, used for API calls.
58+
59+
• Refresh Token – long lived, used to renew sessions.
60+
4. The refresh token is tied to the user, stored in the database, and rotated on use.
61+
62+
>If you lose the refresh token, the session dies. That is life.
63+
64+
## Password Handling
65+
66+
Passwords are hashed using a proper hashing algorithm (no Base64 nonsense). Only hashes are stored. The service handles hashing and verification.
67+
68+
Your password never leaves the service in plain text. The system could not leak it even if it tried.
69+
70+
## UserService – The Traffic Director
71+
72+
This layer does the actual work:
73+
74+
• Registering users.
75+
76+
• Validating credentials.
77+
78+
• Managing tokens.
79+
80+
• Ensuring business rules are respected.
81+
82+
>If something feels too smart for the controller or too specific for the repository, it belongs here.
83+
84+
## DTOs (Data Transfer Objects)
85+
86+
DTOs protect the system from leaking internal structures into the API.
87+
88+
Typical ones:
89+
90+
• UserRegisterDto
91+
92+
• UserLoginDto
93+
94+
• UserDto for returning minimal identity information.
95+
96+
>They shape the data for the outside world so the domain remains clean.
97+
98+
## UsersController – The Doorway
99+
100+
Endpoints typically include:
101+
102+
• POST /users/register – Create a new account.
103+
104+
• POST /users/login – Authenticate and receive tokens.
105+
106+
• POST /users/refresh – Renew access token.
107+
108+
• GET /users/me – Return info about the current user.
109+
110+
>Controllers stay thin. They pass data to services and return results without thinking too much.
111+
112+
## Authorization
113+
114+
Once a user is authenticated, requests carry the Access Token in the Authorization header.
115+
116+
Rules are simple:
117+
118+
• No token → No entry.
119+
120+
• Invalid token → No entry.
121+
122+
• Expired token → Renew using refresh.
123+
124+
>Most protected endpoints have the `[Authorize]` attribute to ensure that only logged‑in users can reach them.
125+
126+
## Error Handling
127+
128+
Authentication failure cases include:
129+
130+
• Wrong email or password.
131+
132+
• Email already registered.
133+
134+
• Expired or missing token.
135+
136+
• Refresh token not found or invalid.
137+
138+
>The API returns appropriate error responses. Clear, predictable, and not misleading.
139+
140+
## Refresh Token Lifecycle
141+
142+
Refresh tokens in Sparkly are treated like long-lived session keys. They live in the database and have a clear lifecycle so they do not turn into immortal zombies.
143+
144+
### Storage
145+
146+
Each refresh token is typically associated with:
147+
148+
• User Id – who owns it.
149+
150+
• Token value – secure random string.
151+
152+
• Expiration date – when it stops being valid.
153+
154+
• Creation time – when it was issued.
155+
156+
• Revocation data (optional) – when and why it was invalidated.
157+
158+
>This allows you to answer questions like: "Is this token still valid?" and "Did we revoke it already?".
159+
160+
### Rotation on Use
161+
162+
Sparkly should use **rotation** when a refresh token is used:
163+
164+
1. Client sends the current refresh token.
165+
2. Server validates it:
166+
167+
• belongs to an existing user,
168+
169+
• not expired,
170+
171+
• not revoked.
172+
3. If valid:
173+
• issue a new access token,
174+
• issue a brand new refresh token,
175+
• revoke (or mark as used) the old refresh token.
176+
177+
>This rotation means that every refresh token is single-use. Once it is exchanged, it should not work again. This greatly limits the damage if one token gets stolen.
178+
179+
### Invalidation Rules
180+
181+
A refresh token can be invalidated when:
182+
183+
• User logs out.
184+
185+
• User changes password.
186+
187+
• Admin forces logout / security reset.
188+
189+
• Token is used and rotated.
190+
191+
>>Invalidation usually means either deleting the token row from the database or marking a `RevokedAt` / `IsRevoked` field.
192+
>
193+
>For extra security, on critical events (like password change) you can invalidate **all** refresh tokens for the user.
194+
195+
### Compromised Token Scenario
196+
197+
If an attacker steals a refresh token, rotation rules help:
198+
199+
• If the legitimate client uses the token first → attacker’s token becomes useless after rotation.
200+
201+
• If the attacker uses it first → legitimate user’s refresh token stops working, which is a strong signal that something is wrong.
202+
203+
You can then:
204+
205+
• invalidate all tokens for that user,
206+
207+
• force re-login,
208+
209+
• optionally log suspicious activity.
210+
211+
### Expiration Strategy
212+
213+
Typical strategy:
214+
215+
• Access token – short lifetime (minutes).
216+
217+
• Refresh token – longer lifetime (days/weeks).
218+
219+
>This gives a good balance between usability and security. Access tokens are cheap, short-lived, and stateless. Refresh tokens are stateful and more powerful, so they are carefully tracked.
220+
221+
## Summary
222+
223+
Users and Authentication in Sparkly are built to be solid, understandable, and easy to maintain. The architecture enforces separation:
224+
225+
• Domain defines what a User is.
226+
227+
• Repository retrieves data.
228+
229+
• Services execute business logic.
230+
231+
• Controllers expose it cleanly.
232+
233+
• JWTs handle authentication.
234+
235+
>The result is a system where you always know where to look. No magic, just structure.

0 commit comments

Comments
 (0)