Create a distributed and self-hosted (via Docker) application to allow Agile teams to track their daily morale.
- Transparency: Visualize collective mood.
- Early Detection: Identify drops in morale.
- Empathy: Understand team challenges.
- Motivation: Encourage use through gamification.
Target Audience: Agile Teams, Managers, Scrum Masters, and project members.
- Backend: RESTful API in .NET 10 (WebAPI).
- Architecture: Skinny Controllers / Fat Services pattern.
- Contracts: Interfaces defined in
NikoNiko.Core/Interfaces. - Logic: Services implemented in
NikoNiko.Services.
- Frontend: React 19+ application with TypeScript, Material UI, Axios, and SWR.
- Database: PostgreSQL / SQLite (configurable).
- Deployment: Docker (3 services: backend, frontend, db) with centralized configuration in
docker/.
- Authentication: OAuth2 (GitHub, Google, Discord). Microsoft is temporarily disabled.
- Team Management: Team creation (up to 2 for regular users), member management (invitations), and administrative settings like Default Sprint Duration and Sprint Name Templates.
- Sprints: Work period definitions with strict validation:
- No overlap: Sprints for the same team cannot have overlapping dates.
- Duration limit: Sprints cannot exceed 2 months (62 days).
- Mood Tracking: Daily recording (🤩/😊/😐/
☹️ /😫) restricted to the current sprint range. Future dates are blocked. - Real-time Notifications: SignalR integration for real-time updates (team creation, rename, member updates, mood entries).
- Gamification: Badge attribution to reward consistency.
- Dashboard: Centralized view of teams, sprints, and calendars, with simplified navigation for users and administrative views for team leads.
User: Profile information and associated OAuth identifiers.Team: Collaborative unit with an admin, members, sprints, and administrative defaults.Sprint: Defined work period linked to a team with start/end dates.MoodEntry: Records of user morale linked to a specific date and sprint.Badge: Gamification achievements.
| Action (Endpoint) | Resource | user |
team-admin |
super-admin |
|---|---|---|---|---|
| Teams | ||||
GET /api/teams |
List teams | Their teams | Their teams | All |
GET /api/teams/{teamId} |
View a team | If member | If member/admin | All |
POST /api/teams |
Create a team | ✓ (Up to 2) | ✓ (Up to 2) | Unlimited |
PUT /api/teams/{teamId} |
Edit a team | No | Only their team | All |
DELETE /api/teams/{teamId} |
Delete a team | No | Only their team | All |
| Users | ||||
GET /api/users |
List users | Team members | Team members | All |
DELETE /api/users/me |
Delete account | ✓ Self only | ✓ Self only | All |
DELETE /api/users/{id} |
Delete user | No | No | All |
DELETE /api/teams/{teamId}/users/{userId} |
Remove from team | No | Only from their team | All |
| Sprints | ||||
GET /api/sprints |
List sprints | Their teams | Their teams | All |
POST /api/sprints |
Create a sprint | No | Only for their team | All |
PUT /api/sprints/{sprintId} |
Edit a sprint | No | Only for their team | All |
DELETE /api/sprints/{sprintId} |
Delete a sprint | No | Only from their team | All |
| Moods | ||||
GET /api/moods/bysprint/{sprintId} |
List moods | Team members | Team members | All |
POST /api/moods |
Record mood | ✓ Within sprint | ✓ Within sprint | ✓ Within sprint |
PUT /api/moods/{id} |
Modify a mood | ✓ Only their own | ✓ Only their own | ✓ Only their own |
| Invitations | ||||
GET /api/teams/{teamId}/invitations |
List invitations | No | Only from their team | All |
POST /api/teams/{teamId}/invitations |
Create invitation | No | Only for their team | All |
DELETE /api/teams/{teamId}/invitations/{invitationId} |
Delete invitation | No | Only from their team | All |
For OAuth 2.0 authentication to work, you must configure external providers.
-
Create an OAuth 2.0 application for each provider:
-
Configure Redirect URIs: When creating your applications, use the following callbacks for the development environment.
- GitHub:
http://localhost:5000/signin-github - Google:
http://localhost:5000/signin-google - Discord:
http://localhost:5000/signin-discord
- GitHub:
-
Update
appsettings.jsonand your.envfile: ReplaceClientIdandClientSecretvalues with your own. Also ensure theJWT_KEYvariable is defined in.env."Authentication": { "GitHub": { "ClientId": "YOUR_GITHUB_CLIENT_ID", "ClientSecret": "YOUR_GITHUB_CLIENT_SECRET" }, "Google": { "ClientId": "YOUR_GOOGLE_CLIENT_ID", "ClientSecret": "YOUR_GOOGLE_CLIENT_SECRET" }, "Discord": { "ClientId": "YOUR_DISCORD_CLIENT_ID", "ClientSecret": "YOUR_DISCORD_CLIENT_SECRET" } // Microsoft is temporarily disabled. }
The project can be configured to use PostgreSQL or SQLite.
-
To use SQLite (default in the
feature/back_sqlitebranch):- In
api/backend/appsettings.json, ensure thatDatabaseProvideris set to"SQLite". - In
docker-compose.yml, thedbservice (PostgreSQL) must be commented out.
- In
-
To switch back to PostgreSQL:
- In
api/backend/appsettings.json, changeDatabaseProviderto"PostgreSQL"(or any value other than "SQLite"). - In
docker-compose.yml, uncomment thedbservice. - Note: EF Core migrations are provider-specific. To change databases, you may need to delete the
Migrationsfolder and create new ones.
- In
EF Core migrations must be executed inside the backend container to ensure access to the mapped SQLite database.
- Ensure the
backendservice is running (at leastdocker compose up -d backend). - Access the
backendcontainer shell:docker compose exec backend bash - Navigate to the API project folder inside the container:
cd /app/api/NikoNiko.Api - Add a new migration (replace
YourMigrationNamewith a descriptive name):dotnet ef migrations add YourMigrationName --project ../NikoNiko.Data --startup-project . - Migrations are applied automatically at
backendservice startup viadbContext.Database.Migrate()inProgram.cs. You don't need to rundotnet ef database updatemanually. - Exit the container shell:
exit
The project uses a split Docker Compose configuration to separate common settings, development specifics, and production overrides.
docker-compose.yml: Base configuration (services, images, env vars).docker-compose.override.yml: Development overrides (ports, test services). Loaded automatically.docker-compose.prod.yml: Production overrides (Traefik labels, networks).
To build and run all services in detached mode for development (loads base + override):
docker compose up -d --buildTo run in production mode (loads base + prod, ignoring dev overrides):
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --buildNote on PostgreSQL data persistence: PostgreSQL database data is now stored in a local directory (./postgres_data) next to the docker-compose.yml file. This facilitates backup and direct management of database data for development environments.
To stop the services:
docker compose downIf you wish to run frontend and/or backend locally without Docker Compose, follow these steps:
- Navigate to the
api/NikoNiko.Apidirectory:cd api/NikoNiko.Api - Install .NET dependencies:
dotnet restore
- After any change in .NET projects, execute
dotnet formatto apply code style preferences defined in.editorconfig. - Update
appsettings.jsonwith your database connection string and OAuth settings. Ensure the PostgreSQL database is running (e.g., viadocker compose up db). - Run the backend API:
The API will typically run on
dotnet run
http://localhost:5000" (or as configured inlaunchSettings.json`).
-
Navigate to the
app/frontenddirectory:cd app/frontend -
Install Node.js dependencies:
npm install # or yarn install -
Start the development server:
npm run dev # or yarn devThe frontend application will typically be accessible at
http://localhost:5173(or as configured by Vite). -
Control every change using ES Lint:
npm run lint
Fix any lint or Typescript error.