15 KiB
Developer Onboarding & Project Guide
Version: 1.0
Status: PRODUCTION
Last Updated: January 2026
Welcome to Job Info
Job Info is a professional web application for managing construction/project jobs, files, and notes. This guide helps new developers understand and maintain the project.
Quick Start (5 minutes)
1. Clone and Setup
git clone <repo-url>
cd Job-Info-Prod
bun install
2. Environment Setup
cp .env.example .env
# Edit .env with your values
Required Variables:
PORT=3005
REDIS_HOST=localhost
REDIS_PORT=6379
POCKETBASE_URL=https://pocketbase.ccllc.pro
3. Start Development
Terminal 1 - Backend:
bun run dev
# Watches backend/server.ts, auto-reloads on changes
Terminal 2 - CSS:
bun run build:css
# Watches Tailwind, auto-compiles output.css
4. Open in Browser
http://localhost:3005
Project Structure
Job-Info-Prod/
├── auth/ # Authentication & rules
│ ├── README.md # Auth module documentation
│ ├── RULES.md # Data handling rules (READ THIS!)
│ ├── FLOWMAP.md # Application flow diagram
│ ├── TECH_STACK.md # Technology versions & usage
│ ├── VIEWS.md # UI/View patterns
│ └── auth-universal.js # Auth implementation
│
├── backend/ # Server code (Hono)
│ ├── src/
│ │ ├── index.ts # Main server entry
│ │ ├── config/ # Configuration
│ │ ├── middleware/ # Auth, logging, CORS
│ │ ├── routes/ # API endpoints
│ │ │ ├── jobs.ts # /api/jobs endpoints
│ │ │ ├── files.ts # /api/job-files endpoints
│ │ │ └── health.ts # /health endpoint
│ │ ├── services/ # Business logic
│ │ │ ├── cache.ts # Redis cache layer
│ │ │ └── pocketbase.ts # PocketBase integration
│ │ ├── types/ # TypeScript interfaces
│ │ └── utils/ # Helper functions
│ ├── tests/ # Unit & integration tests
│ └── README.md # Backend documentation
│
├── frontend/ # Client code (Vanilla JS + Tailwind)
│ ├── public/
│ │ ├── index.html # Main app page
│ │ ├── signin.html # Sign in page
│ │ ├── output.css # Generated Tailwind (don't edit!)
│ │ └── assets/ # Images, logos
│ ├── src/
│ │ ├── main.ts # Frontend entry point
│ │ ├── auth/
│ │ │ └── client.ts # Auth utilities
│ │ ├── views/ # View logic
│ │ │ ├── landing.ts
│ │ │ ├── job-detail.ts
│ │ │ └── notes.ts
│ │ ├── services/ # API & state
│ │ │ ├── api.ts # API client
│ │ │ └── state.ts # Global state
│ │ └── styles/ # Custom CSS
│ ├── tests/
│ └── README.md # Frontend documentation
│
├── shared/ # Shared code
│ ├── types/ # Common TypeScript types
│ └── constants/ # Shared constants
│
├── docs/ # Additional documentation
│ ├── ARCHITECTURE.md # System design
│ ├── API.md # API reference
│ └── DEPLOYMENT.md # Production deployment
│
├── scripts/ # Utility scripts
│ ├── setup.sh # Initial setup
│ └── deploy.sh # Deploy to production
│
├── logs/ # Runtime logs (gitignored)
├── tests/ # Integration tests
│
├── .env.example # Environment template
├── .gitignore # Git ignore rules
├── package.json # Dependencies & scripts
├── tsconfig.json # TypeScript config
├── tailwind.config.js # Tailwind config
├── postcss.config.js # PostCSS config
├── README.md # Project README
└── CHANGELOG.md # Version history
Documentation by Role
For All Developers
Must Read (In Order):
- RULES.md - Data handling & patterns
- FLOWMAP.md - How the app works
- TECH_STACK.md - What tech to use
Reference:
- VIEWS.md - UI component patterns
- API.md - API endpoints
- ARCHITECTURE.md - System design
For Backend Developers
Focus:
- Understand RULES.md - Cache patterns & data flow
- Review backend/README.md
- Follow TECH_STACK.md - Hono patterns
Tasks:
- Create/modify endpoints in
backend/src/routes/ - Implement caching in route handlers
- Add proper error handling & logging
- Write unit tests in
backend/tests/
Key Rules:
- ✅ Cache all GET requests
- ✅ Type all function parameters
- ✅ Log errors with context
- ❌ Don't share state between requests
- ❌ Don't expose secrets
For Frontend Developers
Focus:
- Understand RULES.md - State & view patterns
- Review VIEWS.md - Component design
- Follow TECH_STACK.md - Tailwind patterns
Tasks:
- Create views in
frontend/src/views/ - Implement UI with Tailwind CSS
- Use shared state management
- Handle errors gracefully
Key Rules:
- ✅ Use Tailwind for all styling
- ✅ Keep views modular
- ✅ Use single state object per view
- ❌ Don't inline styles
- ❌ Don't create multiple auth instances
For DevOps/Deployment
Focus:
- Review DEPLOYMENT.md
- Understand environment variables
- Set up CI/CD pipeline
Key Commands:
bun install # Install dependencies
bun run build # Build for production
bun run build:css # Compile Tailwind
bun start # Run production server
Common Development Tasks
Adding a New API Endpoint
1. Define the endpoint in API.md
GET /api/new-resource
Returns: { items: [], total: 0 }
Cache: 5 minutes
Auth: Required
2. Create route in backend/src/routes/new.ts
import { Hono } from 'hono';
import { Context } from 'hono';
import { getCache, setCache } from '../services/cache';
const app = new Hono();
app.get('/api/new-resource', async (c: Context) => {
const cacheKey = 'new-resource:all';
const ttl = 300;
try {
// Try cache
const cached = await getCache(cacheKey);
if (cached) return c.json(cached);
// Fetch data
const data = await fetchNewResources();
// Cache it
await setCache(cacheKey, data, ttl);
return c.json(data);
} catch (err) {
console.error('[new-resource] Error:', err);
return c.json({ error: 'Server error' }, 500);
}
});
export default app;
3. Register route in backend/src/index.ts
import newRoutes from './routes/new';
app.route('/api', newRoutes);
4. Call from frontend
const response = await fetch('/api/new-resource');
const data = await response.json();
Adding a New View
1. Design in VIEWS.md
- Define purpose
- List components
- Sketch HTML structure
2. Create frontend/src/views/new-view.ts
export function renderNewView() {
const container = document.getElementById('app');
container.innerHTML = `
<div class="new-view-container">
<!-- HTML here -->
</div>
`;
// Add event listeners
setupEventListeners();
}
function setupEventListeners() {
const btn = document.getElementById('myButton');
if (btn) {
btn.addEventListener('click', handleButtonClick);
}
}
async function handleButtonClick() {
// Handle click
}
3. Call from frontend/public/index.html
<script>
import { renderNewView } from './src/views/new-view.ts';
window.onNewViewNeeded = () => {
renderNewView();
};
</script>
Modifying Cache Behavior
1. Check RULES.md - Cache section
2. Update cache key format (must follow noun:filter:value pattern)
3. Test cache hit/miss with browser DevTools → Network
4. Document in API.md - Cache TTL
Example:
// OLD: jobs:page:1:10
const cacheKey = `jobs:page:${page}:perPage:${perPage}:sort:${sort}`;
// NEW: jobs:${page}:${perPage}:${sort}
const cacheKey = `jobs:${page}-${perPage}-${sort}`;
Testing
Run Tests
# Backend tests
bun test backend/tests/**/*.test.ts
# Frontend tests (if using Vitest)
bun test frontend/tests/**/*.test.ts
# All tests
bun test
Write Tests
Backend:
// backend/tests/jobs.test.ts
import { expect } from 'bun:test';
import { getJobs } from '../src/routes/jobs';
describe('Jobs API', () => {
it('should cache jobs list', async () => {
const result = await getJobs(1, 10, '-Job_Number');
expect(result).toHaveProperty('items');
});
});
Frontend:
// frontend/tests/auth.test.ts
import { expect } from 'bun:test';
import { isUserLoggedIn } from '../src/auth/client';
describe('Auth', () => {
it('should detect logged in user', () => {
const loggedIn = isUserLoggedIn();
expect(typeof loggedIn).toBe('boolean');
});
});
Debugging
Backend Debugging
1. Check logs:
tail -f logs/server.log # Server logs
tail -f logs/error.log # Error logs
2. Enable verbose logging:
console.log('[endpoint] Request received:', c.req.query());
console.log('[endpoint] Cache key:', cacheKey);
console.log('[endpoint] Cache hit:', cached ? 'YES' : 'NO');
3. Use browser DevTools:
- Network tab → see API requests
- Console tab → see client errors
- Application tab → check localStorage & cookies
Frontend Debugging
1. Browser Console:
// Check auth token
console.log(localStorage.getItem('pocketbase_auth'));
// Check state
console.log(window.fileListState);
// Check cache
console.log(window.fileCache);
2. Check network requests:
- DevTools → Network tab
- Filter by XHR
- Check request/response headers & body
Best Practices
✅ DO
// ✅ Type all functions
async function getJob(jobId: string): Promise<Job | null> {
// Implementation
}
// ✅ Validate input
const page = Math.max(1, parseInt(c.req.query('page') || '1'));
// ✅ Log important events
console.log('[auth] User logged in:', userId);
// ✅ Use cache
const cached = await getCache(key);
if (cached) return c.json(cached);
// ✅ Handle errors gracefully
try {
// ...
} catch (err) {
console.error('Operation failed:', err);
return c.json({ error: 'Server error' }, 500);
}
❌ DON'T
// ❌ Untyped functions
function getJob(jobId) { }
// ❌ Unvalidated input
const page = c.req.query('page');
// ❌ No logging
// Just silently fail
// ❌ No caching
fetch('/api/jobs'); // Every time!
// ❌ Silent failures
try {
// ...
} catch (err) {
// Do nothing
}
Getting Help
Before Asking
- Check documentation - RULES.md, FLOWMAP.md, VIEWS.md
- Search existing code - Find similar patterns
- Check error logs - logs/error.log
- Read the code - Comments explain the "why"
How to Ask
Provide:
- What you were trying to do
- What happened
- What you expected
- Relevant code/logs
Example:
I was trying to add caching to the new /api/jobs-by-manager endpoint.
I created the route but the cache never hits (always MISS).
I expected the second request to return from cache.
Cache key: jobs-by-manager:${managerId}
TTL: 300 seconds
[Cache MISS] logs show it's not finding the cached value.
Version Control
Commit Messages
Format: <type>: <description>
Types:
feat:- New featurefix:- Bug fixdocs:- Documentationrefactor:- Code cleanupperf:- Performance improvementtest:- Add/update tests
Examples:
feat: add caching to jobs list
fix: incorrect file categorization
docs: update API documentation
refactor: simplify state management
perf: optimize database queries
test: add tests for auth flow
Branching
# Create feature branch
git checkout -b feature/new-feature
# Make changes
git add .
git commit -m "feat: add new feature"
# Push and create PR
git push origin feature/new-feature
Before Pushing
- Tests pass
- No console errors
- Follows RULES.md
- Code is commented
- Documentation updated
Deploying to Production
See DEPLOYMENT.md for full instructions.
Quick Summary:
# 1. Test locally
bun test
# 2. Build
bun run build
bun run build:css
# 3. Deploy
# Use your deployment script
# (AWS, Heroku, Docker, etc.)
# 4. Verify
# Check health endpoint
curl https://production-url/health
FAQ
Q: Where do I put new code?
A: Follow the folder structure - routes in backend/src/routes/, views in frontend/src/views/, etc.
Q: How do I add a new dependency?
A: bun add package-name - it auto-updates package.json
Q: Can I use Express instead of Hono?
A: No - see TECH_STACK.md. Stick with Hono for consistency.
Q: How do I debug TypeScript errors?
A: Check your tsconfig.json and enable all strict checks. VSCode will show errors immediately.
Q: Can I skip type annotations?
A: No - RULES.md requires all functions to be typed. Use as unknown if necessary, but avoid it.
Q: How often should I cache?
A: Cache GET requests always. Use TTL of 5-15 minutes depending on data freshness needs.
Staying Updated
Read When Updating Docs
- RULES.md - When adding features
- FLOWMAP.md - When changing user flows
- VIEWS.md - When adding UI
- TECH_STACK.md - When updating dependencies
Update Docs When
- Adding new data patterns
- Changing API contracts
- Adding new views
- Modifying caching strategy
Summary
You now have everything needed to:
- ✅ Understand the application
- ✅ Set up development environment
- ✅ Add new features (backend & frontend)
- ✅ Debug issues
- ✅ Deploy to production
- ✅ Maintain code quality
Most important: Read RULES.md. It covers 90% of development decisions.
Questions? Check the documentation, search the code, or ask senior developers.
Welcome to the team! 🚀