Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,5 @@ https-instance.config

/src/main/webapp/WEB-INF/web.xml
/src/main/resources/local.properties
/src/test/resources/test-db.properties
/src/main/resources/test-db.properties
174 changes: 119 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<div align="center">
<a href="https://github.com/ArchILLtect/code-forge/actions/workflows/ci.yml">
<img alt="CI" src="https://github.com/ArchILLtect/code-forge/actions/workflows/ci.yml/badge.svg">
<img alt="CI" src="https://github.com/ArchILLtect/code-forge/actions/workflows/build-and-package.yml/badge.svg">
</a>
<img alt="Java" src="https://img.shields.io/badge/Java-17-007396?logo=java&logoColor=white">
<img alt="Servlets/JSP" src="https://img.shields.io/badge/Servlets%2FJSP-Tomcat_9-4CAF50">
Expand Down Expand Up @@ -48,39 +48,50 @@ CodeForge’s goal is to provide a *friendlier, clarity-first alternative* to ex
Basic Challenge management (Create/Edit/Delete), list pagination/sorting, filter by difficulty, validation and friendly error pages (404/500).

---
## 📚 Tech Stack

The CodeForge project leverages a modern **Enterprise Java** stack alongside supporting tools for development, testing, and deployment.
## 📚 Tech Stack (Current)

- ### Backend
- **Java 17 (LTS)** — Core language
- **JPA / Hibernate** — ORM layer for database persistence
- Servlets + JSP (Tomcat 9)
- Hibernate 6.x (JPA ORM)
- **Project Lombok** — Reduces boilerplate (getters, setters, builders, etc.)
- **Log4J** — Centralized logging framework (replaces `System.out.println`)
- Log4j2 for application logging
- DAO layer with SessionFactoryProvider

- ### Frontend (Server-Side)
- **JSP / Servlets** — Required for class demonstrations and some views
- **JSTL** — Tag library for dynamic rendering in JSPs
- ### Frontend (Server-Side + Client Enhancements)
- JSP + JSTL for views
- Monaco Editor (CDN) for code editing in Drill/Practice pages
- Minimal vanilla JS for editor sync, hint toggle, and flash messages
- Lightweight CSS (“CodeForge UI”) without a large framework

- ### Database
- **H2 (local/dev)** — Lightweight in-memory DB for rapid testing
- **MySQL / PostgreSQL (prod)** — Relational databases for persistence
- MySQL (local/dev tests and prod)
- Test DB reset via `DbReset` + `cleandb.sql`
- Seed data managed in `src/test/resources/cleandb.sql` (predictable schema)
- **AWS RDS** — Cloud-hosted DB for deployment

- ### Authentication & Security
- **AWS Cognito** — Authentication & authorization service (user registration, login, tokens)
- **Servlet filter (MVP)** — `AuthGuardFilter` protects admin routes and all Drill routes (redirects to `/logIn`)
- Amazon Cognito Hosted UI (servlet-based flow)
- AuthGuardFilter gate for Drill and admin routes
- Public Practice routes (GET/POST) with evaluator feedback, no persistence
- ID token validation (JWKS, RSA256) and HTTP session storage of the user

- ### Evaluator (MVP)
- Evaluator scaffold + ChallengeRunService (non-executing heuristics in MVP)
- Expected answer compare and outcome mapping (CORRECT/ACCEPTABLE/etc.)
- Timeout/memory guard planned for local runner

- ### Testing
- **JUnit 5** — Unit and integration testing
- **Mockito** — (Optional/Stretch) Mocking framework for service/DAO testing
- **Log4J Test Appenders** — Capture and assert logs during test runs
- JUnit 5 test suite
- Mockito for unit tests and servlet/filter behavior stubbing
- DbReset single-source DB reset strategy
- Surefire plugin 3.2.x
- **JaCoCo** — (Optional/Stretch) Test coverage reporting

- ### Build & Deployment
- **Maven** — Dependency management and build tool
- **GitHub Actions** — (Optional/Stretch) CI/CD pipeline (build, test, deploy)
- Maven (3.9.x)
- WAR packaging
- GitHub Actions for CI (build + test + artifact upload)
- **AWS (Elastic Beanstalk / EC2)** — Hosting & deployment
- **Docker** (Stretch) — Containerized environment

Expand Down Expand Up @@ -154,54 +165,77 @@ CodeForge will include challenges from:
- Linked Lists & Trees (basics → moderate)
- Introductory Dynamic Programming

---
## 🚀 Getting Started
### Clone the repository:
# 🚀 Getting Started

## 1️⃣ Clone the repository
```bash
git clone https://github.com/ArchILLtect/code-forge.git
cd code-forge
```

### Set required environment variable for Cognito client secret:
- Windows cmd.exe
```bash
---

## 🔐 Runtime configuration (local development)

### Cognito client secret (required for login)

The Cognito client secret **must NOT be committed**.
Set it via environment variable or JVM system property.

**Windows (PowerShell):**
```powershell
$env:COGNITO_CLIENT_SECRET="your_client_secret"
```

**Windows (cmd.exe):**
```cmd
set COGNITO_CLIENT_SECRET=your_client_secret
```
- PowerShell
```bash
$env:COGNITO_CLIENT_SECRET="your_client_secret"
```
- bash

**macOS / Linux (bash):**
```bash
export COGNITO_CLIENT_SECRET=your_client_secret
```

### Set up test database:
create a MySQL database--MySQL Workbench or command line:
Non-secret Cognito values (user pool ID, region, etc.) live in:
```
src/main/resources/cognito.properties
```

---

## 🧪 Test database setup (required to run tests)

Tests use a **local MySQL test database** and are intentionally isolated from production data.

### 2️⃣ Create a local MySQL test database
```sql
CREATE DATABASE cf_test_db;
```
```

Then create a new file: `src/main/resources/local.properties` with content:
```properties
DB_HOST=<your_host> # e.g., localhost
DB_PORT=<your_port> # default MySQL port is 3306
DB_NAME=<your_database> # e.g., cf_test_db
DB_USER=<your_username> # e.g., root for local
DB_PASS=<your_password>
```

And a file `src/test/resources/hibernate.properties` with content:
Ensure MySQL is running locally.

---

### 3️⃣ Create `src/test/resources/test-db.properties` (untracked)

Create the file:
```
src/test/resources/test-db.properties
```

Example contents:
```properties
hibernate.connection.url=jdbc:mysql://<your_host>:<your_port>/<your_database>?useSSL=false&serverTimezone=UTC
# JDBC for local test database (untracked)
hibernate.connection.url=jdbc:mysql://localhost:3306/cf_test_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
hibernate.connection.driver_class=com.mysql.cj.jdbc.Driver
hibernate.connection.username=<your_username>
hibernate.connection.password=<your_password>
hibernate.dialect=org.hibernate.dialect.MySQLDialect

#pool
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
# Connection pool (local defaults)
hibernate.c3p0.min_size=1
hibernate.c3p0.max_size=10
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=3000
Expand All @@ -210,21 +244,53 @@ hibernate.show_sql=false
hibernate.hbm2ddl.auto=none
```

Ensure you have a local MySQL instance running with a database named `cf_test_db`.
> **Important**
> - Do NOT commit this file.
> - Each contributor must create their own local test DB and properties file.

---

### 4️⃣ How test DB reset works

- `DbReset` runs before each test class.
- It calls `Database.runSQL("cleandb.sql")`.
- `cleandb.sql` lives in `src/test/resources/`.
- Tests always start from a clean, predictable state.

---

### Build and run the project (example with Maven):
## ▶️ Run tests
```bash
mvn clean install
mvn spring-boot:run
mvn -q -DskipTests=false test
```

### Open in your browser at:
---

## 🛠 Build & run the application

### Build the WAR
```bash
http://localhost:5000
mvn clean package
```

### Deploy to Tomcat 9
- Copy `target/codeforge.war` into Tomcat’s `webapps/` directory
- Start Tomcat
- Open:
```
http://localhost:8080/codeforge/
```

---

## ⚠️ Notes on environments

- Production credentials are provided via environment variables (Elastic Beanstalk).
- Local development may temporarily point to production DBs for demo purposes.
- Tests always use the local test DB defined in `test-db.properties` and never touch production data.

---

## Build the WAR:

- Windows cmd.exe
Expand All @@ -244,7 +310,7 @@ Required runtime configuration:

---

## Configuration required by QuoteService (non‑Spring)
## Configuration required by QuoteService
QuoteService loads settings from `src/main/resources/application.properties` at runtime.

Required keys:
Expand Down Expand Up @@ -514,5 +580,3 @@ CodeForge stores static assets (images, JSON files, etc.) in an S3 bucket rather

- ### JSP Usage
`<img src="${cf:asset('banner.png')}" />`

---
28 changes: 14 additions & 14 deletions docs/reflections/TimeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,30 +163,30 @@

---

// TODO: Update this template log for final week activities once the week is complete.
## Week 15 (Dec 8–Dec 14)
| Date | Task | Hours |
|-------------------|----------------------------------------------------------------------------|--------------|
| 12/08 | CodeForge → Added user_id propagation and DAO updates. | 3 |
| 12/08 | CodeForge → Added user_id propagation and DAO updates. | 2 |
| 12/08 | CodeForge → Added expected-answer support + ChallengeService enhancements. | 2 |
| 12/08 | CodeForge → Implemented evaluator pipeline, Normalizer, telemetry logging. | 4 |
| 12/08 | CodeForge → Practice Mode v2 (UI, styles, backend updates). | 3 |
| 12/09 | CodeForge → Monaco editor integration + UI adjustments. | 2.5 |
| 12/08 | CodeForge → Implemented evaluator pipeline, Normalizer, telemetry logging. | 3 |
| 12/08 | CodeForge → Practice Mode v2 (UI, styles, backend updates). | 2 |
| 12/09 | CodeForge → Monaco editor integration + UI adjustments. | 1.5 |
| 12/09 | Ent Java → Time Log update | 2 |
| **Total Week 15** | | **16.5 hrs** |
| 12/10 | Codeforge → Peer review | 4 |
| 12/11 | Codeforge → Doc/Javadoc updates/Hints/JSP upgrades | 5 |
| **Total Week 15** | | **21.5 hrs** |

---

// TODO: Update this template log for final week activities once course is complete.
## Week 16 (Dec 15–Dec 21)
| Date | Task | Hours |
|-------------------|------------------------------------------------------------------------------------|------------|
| 12/09–12/15 | CodeForge → Hibernate config restoration, UTF-8 filter, logout fix, model updates. | 4 |
| 12/09–12/15 | CodeForge → Security polish, token redaction, client ID improvements. | 2 |
| 12/09–12/15 | CodeForge → UI refinements on solve/detail pages, editor tweaks. | 3 |
| 12/09–12/15 | CodeForge → Final documentation updates, deployment checks. | 3 |
| 12/15–12/21 | Ent Java → Final reflections, journal updates, course wrap-up. | 3 |
| **Total Week 16** | | **15 hrs** |
| Date | Task | Hours |
|-------|--------------------------------------------------|-------|
| 12/15 | CodeForge → Checkpoint 3 feedback implementation | 7 |
| 12/16 | CodeForge → Presentation Outline Creation | 4 |
| 12/17 | CodeForge → Presentation Script/Practice | 3 |

| **Total Week 14** | | **-- hrs** |
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table footer shows "Total Week 14" but this is the Week 16 section. It should read "Total Week 16" to match the section header.

Copilot uses AI. Check for mistakes.

---

Expand Down
32 changes: 32 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
<maven.surefire.plugin.version>3.2.5</maven.surefire.plugin.version>
<maven.war.plugin.version>3.4.0</maven.war.plugin.version>
<maven.javadoc.plugin.version>3.6.3</maven.javadoc.plugin.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -197,8 +198,39 @@
<version>${maven.war.plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>${project.build.directory}/site/apidocs</directory>
<targetPath>apidocs</targetPath>
<includes>
<include>**/*</include>
</includes>
<filtering>false</filtering>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven.javadoc.plugin.version}</version>
<executions>
<execution>
<id>generate-web-apidocs</id>
<phase>prepare-package</phase>
<goals>
<goal>javadoc</goal>
</goals>
<configuration>
<failOnError>false</failOnError>
<doclint>none</doclint>
<encoding>UTF-8</encoding>
<source>${maven.compiler.release}</source>
<!-- Generate standard site apidocs into target/site/apidocs -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
* The environment is determined by the "APP_ENV" environment variable,
* defaulting to "dev" if not set.
* @author Nick Hanson
* TODO: Is this still needed, now that spring is gone?
*/
public final class EnvConfig {

Expand Down
14 changes: 13 additions & 1 deletion src/main/java/me/nickhanson/codeforge/config/LocalConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,30 @@

import java.util.Properties;

/**
* Loads local configuration properties from a file.
*/
public class LocalConfig implements PropertiesLoader {

private static Properties localProps;

/**
* Loads the local configuration properties from 'test-db.properties'.
* @return Properties object containing the loaded properties.
*/
public static Properties load() {
if (localProps == null) {
LocalConfig loader = new LocalConfig();
localProps = loader.loadProperties("/local.properties");
localProps = loader.loadProperties("/test-db.properties");
}
return localProps;
}

/**
* Retrieves the value of a specific property by key.
* @param key The property key.
* @return The property value associated with the key.
*/
public static String get(String key) {
Properties props = load();
return props.getProperty(key);
Expand Down
Loading