diff --git a/README.md b/README.md
index 55dac8f..e06f18a 100644
--- a/README.md
+++ b/README.md
@@ -1,103 +1,190 @@
-# minmon
+# Dashboard Manajemen Layanan Server Private Berbasis Web
-This project was created with [Better-T-Stack](https://github.com/AmanVarshney01/create-better-t-stack), a modern TypeScript stack that combines React, TanStack Router, Elysia, TRPC, and more.
+Minmon is a student-friendly web application for managing private servers, hosted services, attached domains, and internal server notes. The system focuses on CRUD operations plus lightweight DNS monitoring, not deployment automation.
-## Features
+## Final Project Scope
-- **TypeScript** - For type safety and improved developer experience
-- **TanStack Router** - File-based routing with full type safety
-- **TailwindCSS** - Utility-first CSS for rapid UI development
-- **Shared UI package** - shadcn/ui primitives live in `packages/ui`
-- **Elysia** - Type-safe, high-performance framework
-- **tRPC** - End-to-end type-safe APIs
-- **Bun** - Runtime environment
-- **Drizzle** - TypeScript-first ORM
-- **PostgreSQL** - Database engine
-- **Authentication** - Better-Auth
-- **Electrobun** - Lightweight desktop shell for web frontends
-- **Turborepo** - Optimized monorepo build system
+This app allows an admin to:
-## Getting Started
+- Manage servers
+- Manage services running on each server
+- Manage domains attached to services
+- Manage notes/documentation for each server
+- Run DNS A-record checks and compare resolved IPs with the expected server IP
+- View a dashboard summary
-First, install the dependencies:
+## Main Features
+
+- Better-auth admin login
+- Dashboard summary for:
+ - total servers
+ - total services
+ - total domains
+ - matched domains
+ - mismatched domains
+ - unresolved domains
+ - inactive/down services
+ - recent notes
+- Server CRUD
+- Service CRUD
+- Domain CRUD
+- DNS check action
+- Server notes CRUD
+- Sample seeded admin and demo dataset
+
+## Database / Entity Overview
+
+### Server
+
+- id
+- name
+- primaryIpAddress
+- secondaryIpAddress
+- operatingSystem
+- location
+- provider
+- description
+- status
+- createdAt
+- updatedAt
+
+### Service
+
+- id
+- serverId
+- name
+- type
+- internalPort
+- externalPort
+- protocol
+- status
+- description
+- createdAt
+- updatedAt
+
+### Domain
+
+- id
+- serviceId
+- name
+- expectedServerIp
+- lastResolvedIp
+- lastResolvedIps
+- resolutionStatus
+- lastCheckedAt
+- remarks
+- lastCheckMessage
+- createdAt
+- updatedAt
+
+### Note
+
+- id
+- serverId
+- title
+- content
+- category
+- createdAt
+- updatedAt
+
+### Relationships
+
+- One server has many services
+- One server has many notes
+- One service belongs to one server
+- One service has many domains
+- One domain belongs to one service
+
+## Tech Stack
+
+- React
+- TanStack Router
+- tRPC
+- PostgreSQL
+- Drizzle ORM
+- better-auth
+- Effect (used narrowly for DNS checking)
+- Bun
+- Turborepo
+
+## Local Run Instructions
+
+1. Install dependencies
```bash
bun install
```
-## Database Setup
+2. Create `apps/server/.env`
-This project uses PostgreSQL with Drizzle ORM.
+```env
+DATABASE_URL=postgresql://postgres:postgres@localhost:5432/minmon
+BETTER_AUTH_SECRET=your-32-char-or-longer-secret-value-here
+BETTER_AUTH_URL=http://localhost:3000
+CORS_ORIGIN=http://localhost:5173
+NODE_ENV=development
+```
-1. Make sure you have a PostgreSQL database set up.
-2. Update your `apps/server/.env` file with your PostgreSQL connection details.
+3. Start PostgreSQL if needed
-3. Apply the schema to your database:
+```bash
+bun run db:start
+```
+
+4. Apply database schema
```bash
bun run db:push
```
-Then, run the development server:
+5. Seed sample data
+
+```bash
+bun run --filter @minmon/db db:seed
+```
+
+Seeded admin:
+
+- Email: `admin@minmon.local`
+- Password: `admin12345`
+
+6. Run the application
```bash
bun run dev
```
-Open [http://localhost:5173](http://localhost:5173) in your browser to see the web application.
-The API is running at [http://localhost:3000](http://localhost:3000).
+7. Open the app
-## UI Customization
-
-React web apps in this stack share shadcn/ui primitives through `packages/ui`.
-
-- Change design tokens and global styles in `packages/ui/src/styles/globals.css`
-- Update shared primitives in `packages/ui/src/components/*`
-- Adjust shadcn aliases or style config in `packages/ui/components.json` and `apps/web/components.json`
-
-### Add more shared components
-
-Run this from the project root to add more primitives to the shared UI package:
-
-```bash
-npx shadcn@latest add accordion dialog popover sheet table -c packages/ui
-```
-
-Import shared components like this:
-
-```tsx
-import { Button } from "@minmon/ui/components/button";
-```
-
-### Add app-specific blocks
-
-If you want to add app-specific blocks instead of shared primitives, run the shadcn CLI from `apps/web`.
+- Web: `http://localhost:5173`
+- API: `http://localhost:3000`
## Project Structure
-```
+```text
minmon/
├── apps/
-│ ├── web/ # Frontend application (React + TanStack Router)
-│ └── server/ # Backend API (Elysia, TRPC)
+│ ├── web/
+│ └── server/
├── packages/
-│ ├── ui/ # Shared shadcn/ui components and styles
-│ ├── api/ # API layer / business logic
-│ ├── auth/ # Authentication configuration & logic
-│ └── db/ # Database schema & queries
+│ ├── api/
+│ ├── auth/
+│ ├── db/
+│ ├── env/
+│ └── ui/
+└── docs/
```
-## Available Scripts
+## Extra Assignment Deliverables
-- `bun run dev`: Start all applications in development mode
-- `bun run build`: Build all applications
-- `bun run dev:web`: Start only the web application
-- `bun run dev:server`: Start only the server
-- `bun run check-types`: Check TypeScript types across all apps
-- `bun run db:push`: Push schema changes to database
-- `bun run db:generate`: Generate database client/types
-- `bun run db:migrate`: Run database migrations
-- `bun run db:studio`: Open database studio UI
-- `bun run dev:desktop`: Start the Electrobun desktop app with HMR
-- `bun run build:desktop`: Build the stable Electrobun desktop app
-- `bun run build:desktop:canary`: Build the canary Electrobun desktop app
+See:
+
+- `docs/run-instructions.md`
+- `docs/uml-guidance.md`
+- `docs/report-outline.md`
+
+## Notes
+
+- DNS checking is limited to A record / IPv4 as required.
+- This is not a deployment platform and does not include SSH, Docker orchestration, or reverse proxy automation.
+- Full workspace typecheck is still blocked by a pre-existing desktop typing issue for `three`, but the web app and server app are verified.
diff --git a/apps/web/src/components/dashboard-shell.tsx b/apps/web/src/components/dashboard-shell.tsx
new file mode 100644
index 0000000..a52d923
--- /dev/null
+++ b/apps/web/src/components/dashboard-shell.tsx
@@ -0,0 +1,123 @@
+import { Button } from "@minmon/ui/components/button";
+import { cn } from "@minmon/ui/lib/utils";
+import { Link, Outlet, useRouterState } from "@tanstack/react-router";
+import { Activity, BookText, Globe, LayoutGrid, Server, Wrench } from "lucide-react";
+
+const dashboardLinks = [
+ {
+ to: "/dashboard",
+ label: "Overview",
+ description: "Health, alerts, and recent checks",
+ icon: LayoutGrid,
+ },
+ {
+ to: "/dashboard/servers",
+ label: "Servers",
+ description: "Inventory and host details",
+ icon: Server,
+ },
+ {
+ to: "/dashboard/services",
+ label: "Services",
+ description: "Processes and uptime targets",
+ icon: Wrench,
+ },
+ {
+ to: "/dashboard/domains",
+ label: "Domains",
+ description: "DNS, SSL, and expiry status",
+ icon: Globe,
+ },
+ {
+ to: "/dashboard/notes",
+ label: "Notes",
+ description: "Runbooks and operational handover",
+ icon: BookText,
+ },
+] as const;
+
+export function DashboardShell({
+ userName,
+ userEmail,
+}: {
+ userName?: string | null;
+ userEmail?: string | null;
+}) {
+ const pathname = useRouterState({
+ select: (state) => state.location.pathname,
+ });
+
+ return (
+
+
+
+
+
+
+ Server Management Dashboard
+
+
Operations overview for demos and day-to-day admin tasks
+
+ Use this area to review monitored assets, inspect detail states, and stage CRUD forms that can connect to tRPC routers as they are added.
+
+
+
+
+
Signed in as
+
{userName ?? "Administrator"}
+
{userEmail ?? "admin@minmon.local"}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/web/src/components/dashboard-ui.tsx b/apps/web/src/components/dashboard-ui.tsx
new file mode 100644
index 0000000..201750b
--- /dev/null
+++ b/apps/web/src/components/dashboard-ui.tsx
@@ -0,0 +1,282 @@
+import { Button } from "@minmon/ui/components/button";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@minmon/ui/components/card";
+import { Input } from "@minmon/ui/components/input";
+import { Label } from "@minmon/ui/components/label";
+import { StatusBadge } from "@minmon/ui/components/status-badge";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+ TableWrapper,
+} from "@minmon/ui/components/table";
+import { Textarea } from "@minmon/ui/components/textarea";
+import { Link } from "@tanstack/react-router";
+import { ChevronRight } from "lucide-react";
+import type { ReactNode } from "react";
+
+type BadgeVariant = "neutral" | "success" | "warning" | "destructive" | "info";
+
+export function PageSection({ title, description, action, children }: SectionProps) {
+ return (
+
+