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
|
||||
|
||||
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 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.
|
||||
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:
|
||||
- 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`
|
||||
The raw session transcripts and interaction logs are included directly in this repository for evaluation access:
|
||||
|
||||
- [Compact Session Transcript (JSONL)](transcripts/transcript.jsonl)
|
||||
- [Full Session Transcript (JSONL)](transcripts/transcript_full.jsonl)
|
||||
|
||||
## Summary of AI Interactions
|
||||
- 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 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 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",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"test": "node --test tests/db.test.js",
|
||||
"lint": "eslint"
|
||||
},
|
||||
"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