Added descriptive step by step approach to configuring the development enviroment
This commit is contained in:
114
README.md
114
README.md
@@ -10,6 +10,96 @@ This project provides a task management interface designed for desktop usage. It
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Step-by-Step Guide for Tutors and Evaluation Marking
|
||||||
|
|
||||||
|
Follow this explicit step-by-step guide to set up, reproduce, test, and run the project from scratch.
|
||||||
|
|
||||||
|
### Step 1: Verify Environment Prerequisites
|
||||||
|
Before running any commands, verify that Node.js (version 18 or higher) and npm are installed on your machine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node -v
|
||||||
|
```
|
||||||
|
Expected output: `v18.x.x` or higher (e.g. `v20.x.x` or `v24.x.x`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm -v
|
||||||
|
```
|
||||||
|
Expected output: `9.x.x` or higher.
|
||||||
|
|
||||||
|
### Step 2: Clone and Navigate to the Repository
|
||||||
|
Open a terminal and clone the repository, then enter the project folder:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/mahlatseclayton/SDP_Lab_1_To-do-app.git
|
||||||
|
cd SDP_Lab_1_To-do-app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Install Dependencies
|
||||||
|
Install all required production and development dependencies specified in `package.json`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are setting up the project manually from a clean environment without `package-lock.json`, you can install the specific packages using the individual commands below:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install core database engine
|
||||||
|
npm install better-sqlite3
|
||||||
|
|
||||||
|
# Install development types and tooling
|
||||||
|
npm install -D @types/better-sqlite3 @types/node @types/react @types/react-dom typescript eslint tailwindcss
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Database Initialization
|
||||||
|
No manual database setup or SQL server configuration is required.
|
||||||
|
- The application uses an embedded SQLite database stored locally in `todo.db`.
|
||||||
|
- When the application starts, `src/lib/db.ts` automatically initializes the `todo.db` database file and creates the required `tasks` table schema if it does not already exist.
|
||||||
|
|
||||||
|
### Step 5: Run Automated Unit Tests
|
||||||
|
To execute the automated unit test suite running against a throwaway in-memory SQLite database (`:memory:`), run the single test command below:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected output:
|
||||||
|
```text
|
||||||
|
✔ 1. Task Creation and Retrieval on throwaway in-memory SQLite database
|
||||||
|
✔ 2. Dynamic Overdue Calculation Rule (read-time comparison)
|
||||||
|
✔ 3. Task Archiving (Soft-deletion) and Unarchiving Verification
|
||||||
|
ℹ pass 3
|
||||||
|
ℹ fail 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 6: Start the Development Server
|
||||||
|
Launch the Next.js local development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected terminal output:
|
||||||
|
```text
|
||||||
|
▲ Next.js 16.2.12 (Turbopack)
|
||||||
|
- Local: http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 7: Open the Application in Your Browser
|
||||||
|
Open your web browser and navigate to:
|
||||||
|
```text
|
||||||
|
http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Note on Port Fallbacks:
|
||||||
|
If port 3000 is already in use on your machine, Next.js will automatically select the next available port (e.g. `http://localhost:3001`). You can also specify a custom port explicitly using:
|
||||||
|
```bash
|
||||||
|
npm run dev -- -p 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Architectural Choices & Key Decisions
|
## Architectural Choices & Key Decisions
|
||||||
|
|
||||||
1. Next.js App Router (Server Components & Server Actions):
|
1. Next.js App Router (Server Components & Server Actions):
|
||||||
@@ -72,30 +162,14 @@ sequenceDiagram
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Environment Requirements & Running Instructions
|
|
||||||
|
|
||||||
### Requirements
|
|
||||||
- Node.js version 18.x or higher
|
|
||||||
- npm package manager
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
```bash
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running the Application
|
|
||||||
```bash
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
Note: Next.js defaults to port 3000. If port 3000 is occupied, Next.js automatically selects the next available port (e.g. 3001), or you can specify a custom port using `npm run dev -- -p <PORT_NUMBER>`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## AI Usage Declaration
|
## AI Usage Declaration
|
||||||
|
|
||||||
AI assistance was utilized during this project for architectural explanations, troubleshooting SQLite schema initialization, and reviewing TSX component patterns. All code additions were executed under guided pair-programming workflows.
|
AI assistance was utilized during this project for architectural explanations, troubleshooting SQLite schema initialization, and reviewing TSX component patterns. All code additions were executed under guided pair-programming workflows.
|
||||||
|
|
||||||
Full session records and transcripts are declared in [docs/AI_TRANSPARENCY.md](docs/AI_TRANSPARENCY.md).
|
Session records and JSONL log files are committed directly in the repository:
|
||||||
|
- [AI Transparency Declaration](docs/AI_TRANSPARENCY.md)
|
||||||
|
- [Compact Session Log (JSONL)](docs/transcripts/transcript.jsonl)
|
||||||
|
- [Full Session Log (JSONL)](docs/transcripts/transcript_full.jsonl)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ In compliance with COMS3011A lab evaluation guidelines, AI assistance was utiliz
|
|||||||
3. Troubleshooting & Debugging: Identifying schema mismatch errors (`table tasks has no column named description`) and providing database migration reset steps.
|
3. Troubleshooting & Debugging: Identifying schema mismatch errors (`table tasks has no column named description`) and providing database migration reset steps.
|
||||||
4. User-Authored Code: All source code modifications were driven interactively and reviewed by the author for complete hands-on learning.
|
4. User-Authored Code: All source code modifications were driven interactively and reviewed by the author for complete hands-on learning.
|
||||||
|
|
||||||
## Conversation Log Transcripts
|
## Conversation Log Transcripts in Repository
|
||||||
|
|
||||||
All raw conversation step logs and prompt histories are preserved locally in the system environment log directory:
|
The raw session transcripts and interaction logs are included directly in this repository for evaluation access:
|
||||||
- Path: `C:\Users\mahla\.gemini\antigravity-ide\brain\1c0b1ab9-bf0e-425f-a67e-38d23d353de7\.system_generated\logs\transcript.jsonl`
|
|
||||||
- Full Transcript: `C:\Users\mahla\.gemini\antigravity-ide\brain\1c0b1ab9-bf0e-425f-a67e-38d23d353de7\.system_generated\logs\transcript_full.jsonl`
|
- [Compact Session Transcript (JSONL)](transcripts/transcript.jsonl)
|
||||||
|
- [Full Session Transcript (JSONL)](transcripts/transcript_full.jsonl)
|
||||||
|
|
||||||
## Summary of AI Interactions
|
## Summary of AI Interactions
|
||||||
- Query 1: Diagnosed `SqliteError: table tasks has no column named description` and provided schema update steps.
|
- Query 1: Diagnosed `SqliteError: table tasks has no column named description` and provided schema update steps.
|
||||||
@@ -24,3 +25,4 @@ All raw conversation step logs and prompt histories are preserved locally in the
|
|||||||
- Query 5: Refactored page inline styles into scoped CSS Modules (`page.module.css`).
|
- Query 5: Refactored page inline styles into scoped CSS Modules (`page.module.css`).
|
||||||
- Query 6: Harmonized UI design system with light page background, royal blue typography, and dark component cards.
|
- Query 6: Harmonized UI design system with light page background, royal blue typography, and dark component cards.
|
||||||
- Query 7: Built Archived Tasks popup dialog with unarchiving / restoring capabilities.
|
- Query 7: Built Archived Tasks popup dialog with unarchiving / restoring capabilities.
|
||||||
|
- Query 8: Added AI session transcripts directly into `docs/transcripts/` directory.
|
||||||
|
|||||||
241
docs/transcripts/transcript.jsonl
Normal file
241
docs/transcripts/transcript.jsonl
Normal file
File diff suppressed because one or more lines are too long
241
docs/transcripts/transcript_full.jsonl
Normal file
241
docs/transcripts/transcript_full.jsonl
Normal file
File diff suppressed because one or more lines are too long
@@ -6,6 +6,7 @@
|
|||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
|
"test": "node --test tests/db.test.js",
|
||||||
"lint": "eslint"
|
"lint": "eslint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
87
tests/db.test.js
Normal file
87
tests/db.test.js
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
const test = require('node:test');
|
||||||
|
const assert = require('node:assert');
|
||||||
|
const Database = require('better-sqlite3');
|
||||||
|
|
||||||
|
// Helper function to initialize throwaway in-memory database
|
||||||
|
function setupInMemoryDb() {
|
||||||
|
const db = new Database(':memory:');
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE tasks (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
due_date TEXT NOT NULL,
|
||||||
|
topic TEXT NOT NULL,
|
||||||
|
status TEXT CHECK(status IN ('Todo','In-Progress','Complete')) NOT NULL DEFAULT 'Todo',
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
is_archived BOOLEAN NOT NULL DEFAULT 0
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to compute overdue dynamically
|
||||||
|
function computeIsOverdue(dueDateStr, status) {
|
||||||
|
if (status === 'Complete') return false;
|
||||||
|
const today = new Date().toISOString().split('T')[0];
|
||||||
|
return dueDateStr < today;
|
||||||
|
}
|
||||||
|
|
||||||
|
test('1. Task Creation and Retrieval on throwaway in-memory SQLite database', () => {
|
||||||
|
const db = setupInMemoryDb();
|
||||||
|
|
||||||
|
const stmt = db.prepare(`
|
||||||
|
INSERT INTO tasks (title, description, due_date, topic, status)
|
||||||
|
VALUES (?, ?, ?, ?, ?)
|
||||||
|
`);
|
||||||
|
const info = stmt.run('Complete Lab Report', 'Detail dynamic overdue rules', '2026-12-31', 'University', 'Todo');
|
||||||
|
|
||||||
|
assert.strictEqual(info.changes, 1);
|
||||||
|
|
||||||
|
const task = db.prepare('SELECT * FROM tasks WHERE id = ?').get(info.lastInsertRowid);
|
||||||
|
assert.strictEqual(task.title, 'Complete Lab Report');
|
||||||
|
assert.strictEqual(task.topic, 'University');
|
||||||
|
assert.strictEqual(task.status, 'Todo');
|
||||||
|
assert.strictEqual(task.is_archived, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('2. Dynamic Overdue Calculation Rule (read-time comparison)', () => {
|
||||||
|
const pastDate = '2020-01-01';
|
||||||
|
const futureDate = '2099-12-31';
|
||||||
|
|
||||||
|
// Past due date with 'Todo' status must be overdue
|
||||||
|
assert.strictEqual(computeIsOverdue(pastDate, 'Todo'), true);
|
||||||
|
|
||||||
|
// Past due date with 'In-Progress' status must be overdue
|
||||||
|
assert.strictEqual(computeIsOverdue(pastDate, 'In-Progress'), true);
|
||||||
|
|
||||||
|
// Past due date with 'Complete' status must NOT be overdue
|
||||||
|
assert.strictEqual(computeIsOverdue(pastDate, 'Complete'), false);
|
||||||
|
|
||||||
|
// Future due date must NOT be overdue
|
||||||
|
assert.strictEqual(computeIsOverdue(futureDate, 'Todo'), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('3. Task Archiving (Soft-deletion) and Unarchiving Verification', () => {
|
||||||
|
const db = setupInMemoryDb();
|
||||||
|
|
||||||
|
// Insert task
|
||||||
|
const info = db.prepare(`
|
||||||
|
INSERT INTO tasks (title, due_date, topic) VALUES ('Archive Test Task', '2026-08-01', 'Testing')
|
||||||
|
`).run();
|
||||||
|
const taskId = info.lastInsertRowid;
|
||||||
|
|
||||||
|
// Archive task (is_archived = 1)
|
||||||
|
db.prepare('UPDATE tasks SET is_archived = 1 WHERE id = ?').run(taskId);
|
||||||
|
let task = db.prepare('SELECT * FROM tasks WHERE id = ?').get(taskId);
|
||||||
|
assert.strictEqual(task.is_archived, 1);
|
||||||
|
|
||||||
|
// Active tasks query must not return archived task
|
||||||
|
const activeTasks = db.prepare('SELECT * FROM tasks WHERE is_archived = 0').all();
|
||||||
|
assert.strictEqual(activeTasks.length, 0);
|
||||||
|
|
||||||
|
// Unarchive task (is_archived = 0)
|
||||||
|
db.prepare('UPDATE tasks SET is_archived = 0 WHERE id = ?').run(taskId);
|
||||||
|
task = db.prepare('SELECT * FROM tasks WHERE id = ?').get(taskId);
|
||||||
|
assert.strictEqual(task.is_archived, 0);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user