2import { Hono } from "https://esm.sh/hono@3.11.7";
3import { readFile, serveFile } from "https://esm.town/v/std/utils@85-main/index.ts";
4import { runMigrations, seedDatabase, resetDatabase } from "./database/migrations.ts";
5
6// Import route handlers
24// }));
25
26// Initialize database on startup
27let dbInitialized = false;
28async function initializeDatabase() {
29 if (!dbInitialized) {
30 try {
31 console.log('Initializing database...');
32 await runMigrations();
33 await seedDatabase();
34 dbInitialized = true;
35 console.log('Database initialized successfully');
36 } catch (error) {
37 console.error('Database initialization failed:', error);
38 throw error;
39 }
43// Health check endpoint
44app.get('/api/health', async (c) => {
45 await initializeDatabase();
46 return c.json({
47 status: 'healthy',
62// Serve the main application
63app.get("/", async (c) => {
64 await initializeDatabase();
65
66 try {
117// Admin routes (serve the same app but with admin flag)
118app.get("/admin", async (c) => {
119 await initializeDatabase();
120
121 try {
2import { Hono } from "https://esm.sh/hono@3.11.7";
3import { setCookie, getCookie, deleteCookie } from "https://esm.sh/hono@3.11.7/cookie";
4import { UserQueries } from "../database/queries.ts";
5
6export const authRoutes = new Hono();
1// Quote API routes for Rancho Shipping Containers
2import { Hono } from "https://esm.sh/hono@3.11.7";
3import { QuoteQueries } from "../database/queries.ts";
4import type { QuoteFormData } from "../../shared/types.ts";
5import { isValidEmail, isValidPhone } from "../../shared/utils.ts";
1// Container API routes for Rancho Shipping Containers
2import { Hono } from "https://esm.sh/hono@3.11.7";
3import { ContainerQueries, ContainerImageQueries } from "../database/queries.ts";
4import type { ContainerFilters, ContainerFormData } from "../../shared/types.ts";
5import { blob } from "https://esm.town/v/std/blob";
1// Database query functions for Rancho Shipping Containers
2import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
3import type {
159
160 /**
161 * Map database row to Container object
162 */
163 private static mapRowToContainer(row: any): Container {
250
251 /**
252 * Map database row to ContainerImage object
253 */
254 private static mapRowToContainerImage(row: any): ContainerImage {
355
356 /**
357 * Map database row to Quote object
358 */
359 private static mapRowToQuote(row: any): Quote {
409
410 /**
411 * Map database row to User object
412 */
413 private static mapRowToUser(row: any): User {
1// Database migrations for Rancho Shipping Containers
2import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
3
4/**
5 * Initialize all database tables
6 */
7export async function runMigrations(): Promise<void> {
8 console.log('Running database migrations...');
9
10 try {
94 await sqlite.execute(`CREATE INDEX IF NOT EXISTS idx_quotes_submitted_at ON quotes (submitted_at)`);
95
96 console.log('Database migrations completed successfully');
97 } catch (error) {
98 console.error('Error running migrations:', error);
104 * Seed initial data for development and testing
105 */
106export async function seedDatabase(): Promise<void> {
107 console.log('Seeding database with initial data...');
108
109 try {
111 const existingContainers = await sqlite.execute('SELECT COUNT(*) as count FROM containers');
112 if (existingContainers[0]?.count > 0) {
113 console.log('Database already has data, skipping seed');
114 return;
115 }
250 }
251
252 console.log('Database seeded successfully');
253 } catch (error) {
254 console.error('Error seeding database:', error);
255 throw error;
256 }
258
259/**
260 * Reset database (for development only)
261 */
262export async function resetDatabase(): Promise<void> {
263 console.log('Resetting database...');
264
265 try {
271
272 await runMigrations();
273 await seedDatabase();
274
275 console.log('Database reset completed');
276 } catch (error) {
277 console.error('Error resetting database:', error);
278 throw error;
279 }
14- `backend/index.ts` - Main HTTP API with Hono
15- `backend/scraper.ts` - Amazon scraping logic
16- `backend/database/` - SQLite database setup and queries
17- `frontend/` - React web interface
18- `scheduler.ts` - Daily cron job for scraping
74โ
**Working Features:**
75- Web interface with React frontend
76- Database storage with SQLite
77- CSV export functionality
78- โ
**Screenshot-based scraping with Steel integration** ๐
18- **Frontend**: React 18.2.0 with TypeScript
19- **Backend**: Hono.js API framework
20- **Database**: SQLite (with migration to PostgreSQL planned)
21- **Styling**: TailwindCSS
22- **Animations**: CSS animations and scroll effects
28```
29โโโ backend/
30โ โโโ database/
31โ โ โโโ migrations.ts # Database schema
32โ โ โโโ queries.ts # Database operations
33โ โโโ routes/
34โ โ โโโ containers.ts # Container CRUD operations
76- **Mobile-Friendly**: Fully responsive admin interface
77
78### Database Schema
79- **Containers**: Product listings with specifications, pricing, status
80- **Container Images**: Multiple images per container with metadata
84## Development Phases
85
861. **Phase 1**: Backend foundation and database setup
872. **Phase 2**: Admin web application development
883. **Phase 3**: Public website core functionality
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { readFile, serveFile } from "https://esm.town/v/std/utils@85-main/index.ts";
3import { initializeDatabase } from "./database/migrations.ts";
4import { saveBooks, getLatestBooks, getBooksHistory } from "./database/queries.ts";
5import { scrapeBooks } from "./scraper.ts";
6import { enhanceBookData } from "./enhancer.ts";
17});
18
19// Initialize database on startup
20await initializeDatabase();
21
22// Serve static files
117 enhancedBooks.push(...result.books.slice(10));
118
119 // Save the enhanced books to database
120 await saveBooks(enhancedBooks);
121 console.log(`Scraping completed: ${enhancedBooks.length} books saved (${Math.min(10, result.books.length)} enhanced)`);
291
292 if (allBooks.length > 0) {
293 // Step 3: Save books to database
294 await saveBooks(allBooks);
295
280 <span className="text-2xl">โ
</span>
281 </div>
282 <p className="text-sm font-medium text-gray-900">Database</p>
283 <p className="text-xs text-green-600">Healthy</p>
284 </div>