Altea is name of company for whom project is dedicated to long run
- Project Overview
- Project Goal
- Key Features
- Technology Stack
- Project Structure
- Getting Started
- Important Notes
- Architecture
- API Documentation
- Frontend Components
- Backend Services
- Database Schema
- Contributing
- License
project is a comprehensive, full-stack construction site management platform built with modern web technologies. It provides end-to-end solutions for managing construction sites, employees, materials, payments, and real-time monitoring through an intuitive dashboard and RESTful API.
The system consists of:
- Frontend: Angular 21 standalone application with real-time updates
- Backend: NestJS REST API with WebSocket support
- Database: PostgreSQL with Prisma ORM
- Infrastructure: Redis caching, Google Maps integration, Firebase notifications
The primary goal of project is to streamline construction site operations by providing:
- Centralized Management: Single platform for all site-related data and operations
- Real-time Monitoring: Live updates on site activities, employee attendance, and material usage
- Cost Control: Track payments, wages, and material costs across multiple sites
- Employee Management: Monitor attendance, roles, and wages for all workers
- Material Inventory: Track stock levels, usage, and low-stock alerts
- Geographic Visualization: Interactive maps showing site locations and status
- Multi-language Support: English and Macedonian (MK) language options
- Role-based Access: Secure authentication with JWT and role-based permissions
- Create, update, and delete construction sites
- Track site status (Active, Planning, Completed, On Hold)
- Geographic location mapping with Google Maps
- Site-specific employee and material assignments
- Cost tracking per site
- Employee profiles with roles and contact information
- Attendance tracking with clock-in/out functionality
- Wage rate management (hourly/daily)
- Role-based permissions (Admin, Manager, Employee)
- Employee assignment to sites
- Inventory tracking across all sites
- Low-stock alerts with configurable thresholds
- Stock addition/usage with description logging
- Material cost calculation
- Site-specific material allocation
- Expandable details panel: Click any material row to view full details (ID, description, timestamps)
- Modal-based actions: Professional dialogs for add stock, use material, and edit operations
- Payment records for employees and contractors
- Monthly payment summaries with Chart.js visualization
- Payment status tracking (Pending, Processing, Completed, Cancelled)
- Payment method support (Cash, Bank Transfer, Check)
- Real-time overview of all operations
- Interactive site location map
- Quick statistics (total employees, active sites, etc.)
- Recent activity feed
- Multi-language toggle (EN/MK)
-
WebSocket integration for live updates
-
Push notifications via Firebase
-
Real-time attendance updates
-
Material stock alerts
- Framework: Angular 21 (Standalone Components)
- Styling: Tailwind CSS + Custom CSS with mint-themed design
- Charts: Chart.js v4.5.1 + ng2-charts v8.0.0
- Maps: Leaflet.js for interactive maps
- i18n: @ngx-translate for multi-language support
- HTTP: Angular HttpClient with RxJS observables
- Authentication: JWT with @auth0/angular-jwt
- Build: Angular CLI v21 with esbuild
- Framework: NestJS v11 (TypeScript)
- Database ORM: Prisma v5.19.1
- Database: PostgreSQL
- Authentication: JWT + Passport
- Caching: Redis with ioredis
- WebSockets: Socket.IO via @nestjs/websockets
- Scheduling: @nestjs/schedule with cron jobs
- Maps API: Google Maps Services (@googlemaps/google-maps-services-js)
- Notifications: Firebase Admin SDK
- Validation: class-validator + class-transformer
- Cache: Redis (cache-manager-redis-yet)
- Database: PostgreSQL with connection pooling
- Real-time: Socket.IO for WebSocket connections
- Task Scheduling: Cron jobs for automated tasks
- API Documentation: RESTful endpoints with proper error handling
site-management-system/
βββ site-management-backend/ # NestJS Backend API
β βββ prisma/ # Database schema and migrations
β β βββ schema.prisma # Prisma database schema
β β βββ seed.ts # Database seeding script
β β βββ migrations/ # Database migration files
β βββ src/
β β βββ auth/ # Authentication module
β β β βββ auth.controller.ts # Login, register endpoints
β β β βββ auth.service.ts # JWT token generation
β β β βββ auth.guard.ts # Route protection
β β β βββ jwt.strategy.ts # JWT validation strategy
β β βββ controllers/ # REST API Controllers
β β β βββ employee.controller.ts
β β β βββ site.controller.ts
β β β βββ material.controller.ts
β β β βββ payment.controller.ts
β β β βββ attendance.controller.ts
β β β βββ role.controller.ts
β β βββ services/ # Business Logic Services
β β β βββ employee.service.ts
β β β βββ site.service.ts
β β β βββ material.service.ts
β β β βββ payment.service.ts
β β β βββ attendance.service.ts
β β βββ models/ # Data Models (DTOs)
β β β βββ employee.model.ts
β β β βββ site.model.ts
β β β βββ material.model.ts
β β β βββ payment.model.ts
β β βββ infrastructure/ # Infrastructure Services
β β β βββ redis.service.ts # Redis caching
β β β βββ maps.service.ts # Google Maps integration
β β β βββ notification-simple.service.ts # Firebase push
β β β βββ task-scheduler.service.ts # Cron jobs
β β β βββ websocket.gateway.ts # WebSocket events
β β βββ db_connect_prisma/ # Database connection
β β β βββ prisma.service.ts
β β βββ app.module.ts # Main application module
β β βββ main.ts # Application entry point
β βββ package.json
β βββ README.md
β
βββ site-management-frontend/ # Angular Frontend
β βββ src/
β β βββ app/
β β β βββ core/ # Core functionality
β β β β βββ guards/ # Route guards
β β β β β βββ auth.guard.ts
β β β β βββ models/ # TypeScript interfaces
β β β β βββ auth.model.ts
β β β βββ features/ # Feature modules
β β β β βββ dashboard/ # Main dashboard
β β β β β βββ dashboard.component.ts
β β β β β βββ dashboard.component.html
β β β β β βββ dashboard.component.css
β β β β βββ employees/ # Employee management (alias: employee)
β β β β β βββ employee.component.ts
β β β β β βββ employee.component.html
β β β β β βββ employee.component.css
β β β β βββ sites/ # Site management
β β β β β βββ sites.component.ts
β β β β β βββ sites.component.html
β β β β β βββ sites.component.css
β β β β βββ materials/ # Materials inventory
β β β β β βββ materials.component.ts
β β β β β βββ materials.component.html
β β β β β βββ materials.component.css
β β β β βββ payments/ # Payment tracking
β β β β β βββ payments.component.ts
β β β β β βββ payments.component.html
β β β β β βββ payments.component.css
β β β β βββ login/ # Authentication
β β β β βββ login.component.ts
β β β β βββ login.component.html
β β β β βββ login.component.css
β β β βββ services/ # API Services
β β β β βββ auth.service.ts
β β β β βββ employee.service.ts
β β β β βββ site.service.ts
β β β β βββ material.service.ts
β β β β βββ payment.service.ts
β β β β βββ attendance.service.ts
β β β β βββ translation.service.ts
β β β βββ shared/ # Shared components
β β β β βββ components/
β β β β βββ contact-support/
β β β βββ app.routes.ts # Route configuration
β β β βββ app.component.ts
β β βββ assets/
β β β βββ i18n/ # Translation files
β β β βββ en.json # English translations
β β β βββ mk.json # Macedonian translations
β β βββ environments/ # Environment configs
β β β βββ environment.ts
β β β βββ environment.development.ts
β β βββ index.html
β β βββ main.ts
β β βββ styles.css # Global styles
β βββ angular.json
β βββ package.json
β βββ tailwind.config.js
β βββ README.md
β
βββ SUPERREADME.md # This file
βββ package.json # Root package (if monorepo)
- Node.js: v18+ (v20+ recommended)
- npm: v10+
- PostgreSQL: v14+
- Redis: v7+ (optional, for caching)
- Google Maps API Key (for maps functionality)
- Firebase Project (for push notifications - optional)
git clone <repository-url>
cd site-management-systemcd site-management-backend
# Install dependencies
npm install
# Configure environment variables
cp .env.example.env OR cp .env.env ( Try both in my instance .env.example but change in both is better )
# Edit .env with your database credentials, JWT secret, API keys
# Run database migrations
npx prisma migrate dev
# Seed the database MUST SEED DATA
npx prisma db seed
# Start development server
npm run start:devBackend runs on: http://localhost:3001
# Site Management Backend Environment Configuration
# Database
DATABASE_URL="postgresql://postgres:23052001@localhost:5432/wfs"
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
# Google Maps API
GOOGLE_MAPS_API_KEY=your_google_maps_api_key
# Firebase Configuration
FIREBASE_PROJECT_ID=site-management-construction
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xyz@site-management-construction.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...\n-----END PRIVATE KEY-----\n"
# Frontend URL for CORS
FRONTEND_URL=http://localhost:3000
# Application Configuration
NODE_ENV=development
PORT=3001
# Security
JWT_SECRET=your_jwt_secret_key_change_this_in_production
JWT_EXPIRES_IN=24h
# Email Configuration (Optional)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_email_password
# Logging
LOG_LEVEL=info
# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
# Check-in Validation
MAX_CHECKIN_DISTANCE_METERS=100
# Notification Settings
DEFAULT_NOTIFICATION_TTL=86400
BATCH_NOTIFICATION_SIZE=1000
# Cache TTL Settings (in seconds)
CACHE_TTL_EMPLOYEE_PROFILE=3600
CACHE_TTL_SITE_COST=1800
CACHE_TTL_ACTIVE_EMPLOYEES=300
CACHE_TTL_SEARCH_RESULTS=600
CACHE_TTL_DASHBOARD_STATS=300
# Background Job Settings
ENABLE_SCHEDULED_JOBS=true
CLEANUP_RETENTION_DAYS=30
cd site-management-frontend
# Install dependencies
npm install
# Start development server
npm start
# or
ng serveFrontend runs on: http://localhost:4200
- Open browser:
http://localhost:4200 - Default credentials (if seeded):
- Email:
duki@example.com - Password:
Duki23052001
- Email:
CRITICAL: Due to event lifecycle issues in the current implementation, initial data may not load automatically on first page render.
Recommended User Flow:
- After Login: You may see empty tables/cards initially
- Trigger Data Load: Click navigation buttons, refresh buttons, or filter options
- Interaction Required: User interaction triggers the event handlers and API calls
- Dashboard Navigation: Click between "Dashboard", "Employees", "Sites", etc. in the sidebar
- Refresh Buttons: Use the "Refresh" button on each page to reload data
Why This Happens:
- Angular lifecycle events (
ngOnInit,AfterViewInit) may complete before WebSocket connections establish - Observable subscriptions in some components require user-triggered events
- Map initialization (Leaflet) needs DOM to be fully rendered before loading markers
Workaround:
- Always click "Refresh" button after navigating to a new page
- Use search/filter inputs to trigger data reload
- Navigate between pages using sidebar buttons to re-initialize components
Future Improvements:
- Add loading skeletons to indicate data is being fetched
- Implement retry logic for failed initial loads
- Add manual "Load Data" button for critical pages
- Fix observable subscription timing in component lifecycle hooks
- JWT tokens expire after 7 days (configurable)
- Tokens are stored in
localStorage(considerhttpOnlycookies for production) - Route guards protect all feature pages except
/login - Role-based access control is partially implemented (extend for production)
- Leaflet.js is used instead of Google Maps for frontend display
- Google Maps Geocoding API is used in backend for address lookups
- Ensure API key has proper permissions for Geocoding API
- Fully responsive design with breakpoints: 1024px, 768px, 480px
- Mobile-first approach with touch-friendly buttons
- Sidebar collapses on mobile (implementation pending)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client (Angular) β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
β HTTP/WebSocket
β
βββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ
β NestJS Gateway β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Controllers (REST API Endpoints) β β
β β - AuthController β β
β β - EmployeeController β β
β β β - SiteController β β
β β - MaterialController β β
β β - PaymentController β β
β ββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββΌββββββββββββββββββββββββββββββββββ β
β β Services (Business Logic) β β
β β - AuthService (JWT) β β
β β - EmployeeService β β
β β - SiteService β β
β β - MaterialService β β
β β - PaymentService β β
β ββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββΌββββββββββββββββββββββββββββββββββ β
β β Infrastructure Services β β
β β - PrismaService (DB ORM) β β
β β - RedisService (Caching) β β
β β - MapsService (Google Maps) β β
β β - NotificationService (Firebase) β β
β β - TaskScheduler (Cron Jobs) β β
β β - WebSocketGateway (Real-time) β β
β ββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ β
β β β
βββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββ΄ββββββββββββ
β β
βββββββββΌβββββββββ ββββββββββΌββββββββββ
β PostgreSQL β β Redis β
β (Database) β β (Cache) β
βββββββββββββββββββ ββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Angular Application β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β App Component (Root) β β
β β - Router Outlet β β
β β - Global Error Handling β β
β ββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββΌββββββββββββββββββββββββββββββββ β
β β Feature Components (Lazy Loaded) β β
β β - DashboardComponent β β
β β - EmployeeComponent β β
β β - SitesComponent β β
β β - MaterialsComponent β β
β β - PaymentsComponent β β
β β - LoginComponent β β
β ββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββΌββββββββββββββββββββββββββββββββ β
β β Services (HTTP + State Management) β β
β β - AuthService (JWT storage) β β
β β - EmployeeService β β
β β - SiteService β β
β β - MaterialService β β
β β - PaymentService β β
β β - TranslationService (i18n) β β
β ββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββΌββββββββββββββββββββββββββββββββ β
β β Guards & Interceptors β β
β β - AuthGuard (Route protection) β β
β β - HttpInterceptor (JWT headers) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β HTTP Requests
β
βββββββββββββΌβββββββββββ
β Backend API (NestJS) β
ββββββββββββββββββββββββ
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /auth/login |
User login (JWT) | No |
| POST | /auth/register |
User registration | No |
| GET | /auth/profile |
Get current user | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /employees |
Get all employees | Yes |
| GET | /employees/:id |
Get employee by ID | Yes |
| POST | /employees |
Create new employee | Yes |
| PATCH | /employees/:id |
Update employee | Yes |
| DELETE | /employees/:id |
Delete employee | Yes |
| GET | /employees/search?q= |
Search employees | Yes |
| POST | /employees/:id/wage |
Update employee wage | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /sites |
Get all sites | Yes |
| GET | /sites/:id |
Get site by ID | Yes |
| POST | /sites |
Create new site | Yes |
| PATCH | /sites/:id |
Update site | Yes |
| DELETE | /sites/:id |
Delete site | Yes |
| GET | /sites/status/:status |
Filter by status | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /materials |
Get all materials | Yes |
| GET | /materials/:id |
Get material by ID | Yes |
| POST | /materials |
Create new material | Yes |
| PATCH | /materials/:id |
Update material | Yes |
| DELETE | /materials/:id |
Delete material | Yes |
| GET | /materials/low-stock |
Get low stock materials | Yes |
| GET | /materials/stats |
Get material statistics | Yes |
| POST | /materials/:id/stock |
Add stock to material | Yes |
| POST | /materials/:id/use |
Use material stock | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /payments |
Get all payments | Yes |
| GET | /payments/:id |
Get payment by ID | Yes |
| POST | /payments |
Create new payment | Yes |
| PATCH | /payments/:id |
Update payment | Yes |
| DELETE | /payments/:id |
Delete payment | Yes |
| GET | /payments/monthly-summary |
Get monthly chart data | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /attendance/clock-in |
Clock in employee | Yes |
| POST | /attendance/clock-out |
Clock out employee | Yes |
| GET | /attendance/employee/:id |
Get employee logs | Yes |
| GET | /attendance/site/:id |
Get site attendance | Yes |
Purpose: Main overview page with statistics, maps, and quick actions
Features:
- Real-time site overview cards
- Interactive Leaflet map with site markers
- Quick statistics (employees, active sites, planning sites)
- Recent activity feed
- Multi-language toggle (EN/MK)
- Sidebar navigation to all modules
Styling: Mint-themed gradient design with card-based layout
Purpose: Manage employee records, attendance, and wages
Features:
- Employee list with search functionality
- Add/Edit/Delete employees
- Wage rate management
- Role assignment
- Attendance tracking
- Premium search input with mint gradient
Styling: Table-based layout with mint-themed search and buttons
Purpose: Manage construction sites and their status
Features:
- Site cards with status indicators
- Geographic map view
- Add/Edit/Delete sites
- Status filtering (Active, Planning, Completed, On Hold)
- Employee and material assignment per site
- Premium search with mint theme
Styling: Grid layout for site cards with interactive hover effects
Purpose: Track inventory, stock levels, and material usage
Features:
- Material inventory table with expandable details
- Click-to-expand rows: View full material details (ID, description, timestamps)
- Modal dialogs for all actions:
- Add Stock Modal: Quantity input + optional description
- Use Material Modal: Quantity validation with warning for insufficient stock
- Edit Material Modal: Update name, unit, description
- Low-stock alerts with configurable threshold
- Stats cards (Total Materials, Low Stock, Out of Stock)
- Site-specific material filtering
- Premium search input with mint gradient and search icon
- Mint-themed buttons with gradient backgrounds and hover effects
Styling:
- Mint-themed modal dialogs with smooth animations
- Gradient buttons (mint, amber, blue, red) for different actions
- Expandable detail panels with bordered layout
- Professional form inputs with focus states
Purpose: Track payments to employees and contractors
Features:
- Payment history table
- Monthly summary chart (Chart.js bar chart)
- Payment status tracking
- Add/Edit/Delete payments
- Payment method selection
- Stats cards
Styling: Chart visualization with table layout
Purpose: User authentication
Features:
- Email/Password login
- JWT token storage
- Form validation
- Error handling
- Redirect to dashboard on success
Styling: Centered card with brand colors
- User authentication with bcrypt password hashing
- JWT token generation and validation
- User registration with role assignment
- Passport JWT strategy
- CRUD operations for employees
- Search functionality
- Wage calculation
- Employee-site relationships
- Attendance log integration
- CRUD operations for sites
- Status management
- Google Maps geocoding for addresses
- Site statistics calculation
- Material and employee associations
- Inventory management
- Stock addition/usage tracking
- Low-stock alerts
- Site-specific material queries
- Statistics (total, low stock, out of stock)
- Payment record management
- Monthly summaries for charts
- Payment status updates
- Employee payment history
- Caching frequently accessed data
- Session storage
- Real-time data sync
- Google Maps Geocoding API integration
- Address to coordinates conversion
- Distance calculations
- Firebase push notifications
- Real-time alerts for low stock
- Attendance notifications
- Cron jobs for automated tasks
- Daily reports generation
- Stock level monitoring
- Real-time updates via Socket.IO
- Attendance events
- Material usage events
- Site status changes
user_id(PK)email(unique)password_hashfirst_namelast_namerole_id(FK β roles)created_atupdated_at
role_id(PK)role_name(unique: 'admin', 'manager', 'employee')description
employee_id(PK)first_namelast_nameemailphone_numberhourly_wage/daily_wagerole_id(FK β roles)site_id(FK β sites)created_atupdated_at
site_id(PK)site_nameaddresslatitudelongitudestatus(enum: 'active', 'planning', 'completed', 'on_hold')start_dateend_datecreated_atupdated_at
material_id(PK)namedescriptionquantityunit(e.g., 'kg', 'm', 'pieces')site_id(FK β sites)created_atupdated_at
payment_id(PK)employee_id(FK β employees)amountpayment_datepayment_method(enum: 'cash', 'bank_transfer', 'check')status(enum: 'pending', 'processing', 'completed', 'cancelled')descriptioncreated_atupdated_at
log_id(PK)employee_id(FK β employees)site_id(FK β sites)clock_inclock_outtotal_hourscreated_at
usersβroles(many-to-one)employeesβroles(many-to-one)employeesβsites(many-to-one)materialsβsites(many-to-one)paymentsβemployees(many-to-one)attendance_logsβemployees(many-to-one)attendance_logsβsites(many-to-one)
Primary (Mint Green):
#6ee7b7- Light mint (hover states)#10b981- Main mint (primary actions)#059669- Dark mint (text on mint bg)
Neutrals:
#ffffff- White (backgrounds)#f9fafb- Light gray (hover backgrounds)#e5e7eb- Gray (borders)#6b7280- Medium gray (secondary text)#111827- Dark gray (primary text)
Status Colors:
#3b82f6- Blue (info, edit actions)#fbbf24- Amber (warnings, use actions)#ef4444- Red (errors, delete actions)#10b981- Green (success, add actions)
- Headings: Inter (system font fallback)
- Body: System font stack
- Base Size: 14px-16px
- Line Height: 1.5-1.75
- Base Unit: 4px
- Common Spacing: 8px, 12px, 16px, 20px, 24px, 32px
- Small: 6px-8px (buttons, inputs)
- Medium: 10px-12px (cards, modals)
- Large: 16px (large cards)
- Round: 50% (avatars)
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open Pull Request
Backend (NestJS):
- Follow NestJS best practices
- Use Prettier for formatting
- ESLint for linting
- DTOs for validation
- Service-Repository pattern
Frontend (Angular):
- Angular style guide compliance
- Standalone components preferred
- RxJS for async operations
- Avoid
anytype - Use
OnPushchange detection where possible
Backend:
npm run test # Unit tests
npm run test:e2e # E2E tests
npm run test:cov # Coverage reportFrontend:
ng test # Unit tests with Vitest
ng e2e # E2E testsThis project is licensed under the UNLICENSED license - see backend package.json for details.
For commercial use, please contact the project maintainers.
For issues, questions, or feature requests:
- GitHub Issues: Open an issue in this repository
- Contact Support: Use the in-app "Contact Support" modal
- Email: admin@altea.com
- Fix initial data loading issues
- Add loading skeletons
- Implement real-time notifications
- Mobile sidebar collapse
- Export data to PDF/Excel
- Advanced reporting dashboard
- Gantt chart for site timelines
- Budget forecasting
- Employee performance metrics
- Mobile app (React Native)
- Multi-tenant support
- Advanced role-based permissions
- Integration with accounting software
- AI-powered cost predictions
- Offline mode with sync
- Clone repository
- Install Node.js v18+
- Install PostgreSQL
- Set up backend
.envfile - Run database migrations
- Start backend server (
npm run start:dev) - Configure frontend environment
- Start frontend server (
ng serve) - Test login with default credentials
- Click "Refresh" buttons on each page after navigation
- Explore all feature modules
- Read API documentation
- Review database schema
- Check console for errors
Happy Coding! π
Built with β€οΈ using Angular, NestJS, and PostgreSQL.