Skip to content

Latest commit

 

History

History
318 lines (220 loc) · 6.07 KB

File metadata and controls

318 lines (220 loc) · 6.07 KB

Development Guide

Complete guide for ShadowCheck development


Prerequisites

  • Node.js 22+ (LTS recommended)
  • PostgreSQL 18+ with PostGIS extension
  • Docker (optional, for containerized development)
  • Git

Initial Setup

1. Clone Repository

git clone https://github.com/cyclonite69/shadowcheck-web.git
cd shadowcheck-web

2. Install Dependencies

npm install

3. Configure Environment

# Secrets policy: do not create local .env files with credentials; use AWS Secrets Manager or explicit env-var overrides
docker compose up -d

4. Start Development

# Terminal 1: Backend
npm run dev

# Terminal 2: Frontend
npm run dev:frontend

DevContainer Setup (Recommended)

Prerequisites

  • Docker Desktop
  • VS Code with Dev Containers extension

Steps

  1. Open in DevContainer (VS Code will prompt)
  2. Wait for container build
  3. Start developing:
    npm run dev          # Backend (port 3001)
    npm run dev:frontend # Frontend (port 5173)

Development Workflow

Local Shell Helpers

To streamline local development, source the included helper aliases:

source ./scripts/local-dev-aliases.sh

Common Tasks:

  • scroot - Repository root navigation.
  • sclocal - Generic docker compose wrapper.
  • scapi - Reset/rebuild API with AWS development defaults.
  • scgrafana - Launch local monitoring stack.
  • scdb - Connect to shadowcheck_user database.
  • scdba - Connect to shadowcheck_admin database.

Available Scripts

# Development

**Docs version (repo):** [docs/DEVELOPMENT.md](../../docs/DEVELOPMENT.md)
npm run dev              # Backend with nodemon
npm run dev:frontend     # Frontend with Vite HMR

# Building
npm run build            # Build frontend and server
npm run build:frontend   # Build React app
npm run build:server     # Compile TypeScript

# Testing
npm test                 # Run all tests
npm run test:cov         # Tests with coverage
npm run test:integration # Integration tests only

# Code Quality
npm run lint             # ESLint check
npm run lint:fix         # Auto-fix issues
npm run format:check     # Prettier check
npm run format           # Auto-format

# Docker
npm run docker:up        # Start containers
npm run docker:down      # Stop containers

Adding a New API Endpoint

  1. Create route handler in server/src/api/routes/v1/:
// server/src/api/routes/v1/my-feature.ts
import { Router } from 'express';
import { container } from '../../../config/container';

const router = Router();

router.get('/', async (req, res, next) => {
  try {
    const service = container.get('myService');
    const data = await service.getData();
    res.json({ ok: true, data });
  } catch (err) {
    next(err);
  }
});

export default router;
  1. Add business logic in server/src/services/:
// server/src/services/myService.ts
export class MyService {
  async getData() {
    // Business logic here
  }
}
  1. Register in container:
// server/src/config/container.ts
container.register('myService', new MyService());
  1. Mount route in server initialization

Adding a Frontend Component

  1. Create component:
// client/src/components/MyComponent.tsx
import React from 'react';

export const MyComponent: React.FC = () => {
  return <div className="p-4">My Component</div>;
};
  1. Add route in App.tsx:
import { lazy } from 'react';
const MyComponent = lazy(() => import('./components/MyComponent'));

<Route path="/my-route" element={<MyComponent />} />;
  1. Add navigation link in Navigation.tsx

Database Management

Common Operations

# Connect to database
docker exec -it postgres psql -U shadowcheck_user -d shadowcheck_db

# Run migration
docker exec -i postgres psql -U shadowcheck_user -d shadowcheck_db < sql/migrations/your_migration.sql

# Backup database
pg_dump -U shadowcheck_user -d shadowcheck_db -F c -f backup_$(date +%Y%m%d).dump

Useful Queries

-- Count networks by type
SELECT type, COUNT(*) FROM public.networks GROUP BY type;

-- Recent observations
SELECT * FROM public.observations
WHERE time >= EXTRACT(EPOCH FROM NOW() - INTERVAL '1 day') * 1000
LIMIT 10;

-- Tagged networks
SELECT bssid, tag_type, confidence FROM app.network_tags;

Testing

Run Tests

# All tests
npm test

# Specific test
npm test -- tests/unit/your-test.test.js

# With coverage
npm run test:cov

Writing Tests

// tests/api/dashboard-metrics.test.js
const request = require('supertest');
const app = require('../../server');

describe('GET /api/dashboard-metrics', () => {
  it('should return dashboard metrics', async () => {
    const response = await request(app).get('/api/dashboard-metrics').expect(200);

    expect(response.body).toHaveProperty('totalNetworks');
  });
});

Code Quality

Pre-commit Hooks

Husky runs automatically for repo checks such as the secret-scan flow.

  • ESLint
  • Prettier
  • Secret scanning

CI also runs secret scanning on push / PR and a scheduled full-history scan, so local hooks are not the only enforcement layer.

Commit Message Format

Follow Conventional Commits:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • test: Test additions
  • refactor: Code refactoring
  • chore: Maintenance tasks

Troubleshooting

Database Connection Errors

# Verify Docker PostgreSQL is running
docker ps | grep postgres

# Test connection
docker exec postgres psql -U shadowcheck_user -d shadowcheck_db

Port Already in Use

# Find process using port
lsof -i :3001

# Kill process
kill -9 <PID>

Memory Issues

# Increase Node.js heap size
NODE_OPTIONS="--max-old-space-size=4096" npm start

Related Documentation