Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
6de98b7
(ai) first home page non-auth
teamssUTXO May 8, 2026
d565746
add hand-off
teamssUTXO May 8, 2026
20ca003
update hand-off
teamssUTXO May 9, 2026
2d5d664
add i18n vscode extension
teamssUTXO May 9, 2026
b9cf837
chore : update infra & repo file
teamssUTXO May 12, 2026
924883e
feat : add login + group features
teamssUTXO May 12, 2026
2512cf1
chore : remove target dir
teamssUTXO May 12, 2026
f1d2394
fix : coderabbit comments
teamssUTXO May 14, 2026
ccd07ad
fix : coderabbit comments
teamssUTXO May 14, 2026
fc96efb
fix : method in two entity
teamssUTXO May 14, 2026
903f4cd
Merge pull request #4 from CodeStar-Project/front/home-page-non-auth …
teamssUTXO May 14, 2026
fb3e32e
feat : add front connected to backend
teamssUTXO May 15, 2026
4fd1cef
fix : coderabbit comments
teamssUTXO May 15, 2026
2bca540
fix : coderabbit comments
teamssUTXO May 16, 2026
fe71ddf
feat : add state token
teamssUTXO May 16, 2026
f916762
Bump node.js to 20.9.0
teamssUTXO May 16, 2026
1946d59
fix : docker with .env
teamssUTXO May 16, 2026
316c46d
Merge pull request #5 from CodeStar-Project/feat/front-login
teamssUTXO May 16, 2026
b884d70
chore : update docker infrastructure
teamssUTXO May 17, 2026
8f267e7
Merge pull request #7 from CodeStar-Project/update-docker-infra
teamssUTXO May 17, 2026
10e0c02
add course and course block management with REST AP
AntoninMignotPilon May 17, 2026
cafa765
fix : delete comments
AntoninMignotPilon May 20, 2026
547dbbd
ajout de la classe de config pour swagger
AntoninMignotPilon May 20, 2026
a18f6c5
feat : add global course management
teamssUTXO May 26, 2026
b9125f4
fix : coderabbit comments
teamssUTXO May 26, 2026
ae4476b
feat : add /mine endpoint + DB upsert for enrollments
teamssUTXO May 26, 2026
3a4692b
fix : coderabbit comment
teamssUTXO May 26, 2026
ffafebb
Merge pull request #8 from CodeStar-Project/back/addCourses
teamssUTXO May 26, 2026
0fb0ce4
feat/add-course-frontend
teamssUTXO May 26, 2026
be79f60
fix : build on docker
teamssUTXO May 26, 2026
0919687
fix : get course methods now transactional
teamssUTXO May 27, 2026
fb5d552
feat : add minimalistique course builder
teamssUTXO May 27, 2026
d88d9df
fix : coderabbit comments
teamssUTXO May 28, 2026
18bc6e8
Merge pull request #12 from teamssUTXO/feat/course-management-front
teamssUTXO May 28, 2026
4efe1aa
fix : user and group little addons & fixes
teamssUTXO May 28, 2026
4e38382
feat (groups) : add group delete action
teamssUTXO May 28, 2026
76b8680
fix : rm statsservice references
teamssUTXO May 28, 2026
fcef0d5
fix : coderabbit comments (back & front actions/libs))
teamssUTXO May 29, 2026
4670f0f
update info text on course delete
teamssUTXO May 30, 2026
7aa2846
Merge pull request #14 from teamssUTXO/fix/group-course-management
teamssUTXO May 30, 2026
423772d
docs(chore) : update hand-off
teamssUTXO Jun 1, 2026
c6b6273
Merge pull request #16 from teamssUTXO/chore/update-handoff
teamssUTXO Jun 1, 2026
0c026ff
fix : backenf build groupStatsService not found
teamssUTXO Jun 2, 2026
b16dcaa
Merge pull request #17 from teamssUTXO/dev
teamssUTXO Jun 2, 2026
73ad676
chore : update hand-off
teamssUTXO Jun 2, 2026
e3107c8
Merge pull request #18 from teamssUTXO/dev
teamssUTXO Jun 2, 2026
56333a0
fix : catch getPublishedCourses error
teamssUTXO Jun 3, 2026
7156764
feat(course builder) : add course builder backend + import/export + n…
teamssUTXO Jun 3, 2026
7a95f23
fix(course reader) : next page button
teamssUTXO Jun 3, 2026
5818dbd
fix : add backend healthcheck when start frontend and require auth fo…
teamssUTXO Jun 3, 2026
a3559ea
chore(docs) : update hand-off
teamssUTXO Jun 3, 2026
53aa89b
fix : coderabbit comments
teamssUTXO Jun 4, 2026
98d03b8
Merge pull request #19 from teamssUTXO/feat/course-builder
teamssUTXO Jun 4, 2026
2ce02e1
feat(media) : image management (v1 file system)
teamssUTXO Jun 7, 2026
19b1e2e
Update SecurityConfig.java
teamssUTXO Jun 7, 2026
be8bad6
fix(env) : jwt duration
teamssUTXO Jun 7, 2026
301756e
update .env.example
teamssUTXO Jun 7, 2026
ae3adeb
feat(media) : add media asset storage, quotas and rate limiter
teamssUTXO Jun 7, 2026
dae58ba
chore : update hand-off with media's PR
teamssUTXO Jun 7, 2026
7f6e3a8
refactor : add config properties and rate-limit eviction
teamssUTXO Jun 8, 2026
8dc31ad
chore : coderabbit nitpicks
teamssUTXO Jun 8, 2026
58a32f1
Merge pull request #21 from teamssUTXO/feat/images-management
teamssUTXO Jun 8, 2026
34b1f49
add front-end roadmap
teamssUTXO Jun 8, 2026
decfcc2
Merge pull request #24 from teamssUTXO/chore/prepare-front-revamp
teamssUTXO Jun 8, 2026
2ae8743
docs: add AI course generator design spec
lmrt0572 Jun 9, 2026
549273e
chore(ai): add AiProperties config and .env.example entries
lmrt0572 Jun 9, 2026
f9d4f12
feat(ai): add GenerateCourseRequestDto and GenerateCourseResponseDto
lmrt0572 Jun 9, 2026
9458a99
feat(ai): implement AiRateLimiter token bucket
lmrt0572 Jun 9, 2026
b7df1f6
feat(ai): implement AiCourseService with prompt builder and response …
lmrt0572 Jun 9, 2026
76f7c30
feat(ai): implement AiCourseController POST /api/v1/ai/courses/generate
lmrt0572 Jun 9, 2026
a9f9831
chore(ai): wire AI env vars into docker-compose backend service
lmrt0572 Jun 10, 2026
a957316
feat(ai): improve system prompt richness and normalize level field
lmrt0572 Jun 10, 2026
03d283f
feat(ai): add AI course generator page and actions
lmrt0572 Jun 10, 2026
583d844
fix(course-reader): make bookmark button icon-only on desktop
lmrt0572 Jun 10, 2026
3a2958e
feat(logs) : add audit logging + request context and actuator
teamssUTXO Jun 10, 2026
02b1712
Update hand-off with new log feature
teamssUTXO Jun 10, 2026
3c75182
Update comments
teamssUTXO Jun 10, 2026
511cf11
fix : coderabbit comments
teamssUTXO Jun 10, 2026
54089d0
chore : remove dead method
teamssUTXO Jun 10, 2026
ed93e0a
chore : coderabbit nitpick
teamssUTXO Jun 10, 2026
4833c84
Merge pull request #29 from teamssUTXO/feat/add-logs
teamssUTXO Jun 10, 2026
817a897
refactor(i18n) : add i18n keys
teamssUTXO Jun 12, 2026
cab8861
Merge branch 'dev' into fork/lmrt0572/feat/ai-course-generator-front
teamssUTXO Jun 12, 2026
b3fe8b1
refactor : increase AI response max_token
teamssUTXO Jun 13, 2026
3d378b9
Merge branch 'dev' into pr/lmrt0572/27
teamssUTXO Jun 13, 2026
0503315
feat : add logging
teamssUTXO Jun 13, 2026
e6dbf7a
refactor : add sweep/eviction in AI rate limiter
teamssUTXO Jun 13, 2026
e7a24f0
fix(ai): map upstream HTTP errors to distinct statuses
teamssUTXO Jun 13, 2026
0b34165
refactor : prompt, level and temperature security
teamssUTXO Jun 13, 2026
d5d3d8b
refactor(ai): harden course generator per review
teamssUTXO Jun 13, 2026
f693219
Update AiCourseService.java
teamssUTXO Jun 13, 2026
5ba9d0f
refactor: merge AI/import DTOs into CoursePayloadDto
teamssUTXO Jun 13, 2026
a2f1ca6
refactor : add new blocks in prompt
teamssUTXO Jun 13, 2026
758d2ad
Update hand-off with AI course generator
teamssUTXO Jun 13, 2026
650e371
Merge pull request #27 from lmrt0572/feature/ai-course-generator
teamssUTXO Jun 13, 2026
15ca67a
Merge branch 'dev' into fork/lmrt0572/feat/ai-course-generator-front
teamssUTXO Jun 14, 2026
273a5b5
chore : add frontend design doc into doc dir + update init.sql comment
teamssUTXO Jun 14, 2026
20f527e
refactor(front): i18n AI generator + harden its server action
teamssUTXO Jun 14, 2026
fa78cf6
refactor : change course version
teamssUTXO Jun 14, 2026
c2261d7
fix : coderabbit nitpick
teamssUTXO Jun 14, 2026
47f0ca6
feat(ai): add prompt help popover with writing tips
lmrt0572 Jun 15, 2026
53f14d8
Merge pull request #28 from lmrt0572/feat/ai-course-generator-front
teamssUTXO Jun 16, 2026
edfd727
feat(log) : add nect.js server-side logger
teamssUTXO Jun 18, 2026
77d12aa
Merge branch 'dev' into feat/add-front-logs
teamssUTXO Jun 18, 2026
ba633ff
doc : add log comment
teamssUTXO Jun 18, 2026
0aa1ea9
fix : coderabbitai comments
teamssUTXO Jun 19, 2026
d49f8e6
Merge pull request #31 from teamssUTXO/feat/add-front-logs
teamssUTXO Jun 19, 2026
672e30d
docs : update hand-off by removing merging in old files
teamssUTXO Jun 19, 2026
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
48 changes: 45 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,53 @@ DB_NAME=codestardb

# Spring Boot / JWT
JWT_SECRET=change_me_use_a_long_random_string_at_least_64_chars
JWT_EXPIRATION=86400000
JWT_EXPIRATION=604800000 # one week by default (in milliseconds)

# Signup open (true = No invitation code needed)
SIGNUP_OPEN=true

# Bootstrap super-admin on first boot.
# If the email exists in the database with a lower role, it is promoted. The password NEVER overwrites an existing user.
CODESTAR_BOOTSTRAP_SUPER_ADMIN_EMAIL=example@gmail.com
CODESTAR_BOOTSTRAP_SUPER_ADMIN_PASSWORD=change_me_to_a_strong_password
CODESTAR_BOOTSTRAP_SUPER_ADMIN_DISPLAY_NAME=John

# Ports (optional — defaults shown)
BACKEND_PORT=8080
FRONTEND_PORT=3000

# Next.js — URL the browser uses to reach the backend API
NEXT_PUBLIC_API_URL=http://localhost:8080
# Path to an external branding JSON file (optional) - Leave empty to use the bundled default
# You can customize the branding either by pointing to an external file OR by editing the bundled one.
INSTANCE_CONFIG_PATH=

# Frontend
# Backend & Frontend base URL
API_URL=http://localhost:8080
SITE_URL=http://localhost:3000
# Name of the httpOnly cookie storing the JWT (must match backend + frontend code expectations).
AUTH_COOKIE_NAME=codestar_token


# Media storage (course images) — quotas
# Reject uploads that would push a single user (or the whole instance) over the cap (HTTP 413).
MEDIA_USER_QUOTA_MB=100
MEDIA_INSTANCE_QUOTA_MB=5000

# Media upload rate limit per user (token bucket) — over the limit returns HTTP 429.
# capacity = burst size; refill = tokens added back per minute.
MEDIA_RATE_LIMIT_CAPACITY=20
MEDIA_RATE_LIMIT_REFILL_PER_MINUTE=20

# Spring runtime profile (optional): prod (default) or dev.
# SPRING_PROFILES_ACTIVE=prod

# AI Course Generator
AI_API_URL=https://api.groq.com/openai/v1
AI_API_KEY=
AI_MODEL=llama-3.3-70b-versatile
AI_MAX_TOKENS=16384
AI_TEMPERATURE=0.4
AI_CONNECT_TIMEOUT_SECONDS=5
AI_TIMEOUT_SECONDS=90
AI_RATE_LIMIT_CAPACITY=5
AI_RATE_LIMIT_REFILL_PER_MINUTE=2
73 changes: 70 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,80 @@
# Environment secrets
# Environment / secrets
.env
.env.*
!.env.example
*.pem
*.key
*.crt

# OS
.DS_Store
.AppleDouble
.LSOverride
._*
.Spotlight-V100
.Trashes
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
Desktop.ini
$RECYCLE.BIN/
*.lnk
.fuse_hidden*
.directory
.Trash-*
.nfs*

# IDE
# IDE / Editors
.idea/
*.iml
*.iws
*.ipr
out/

# Claude
# VS Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
.history/

# Eclipse
.classpath
.project
.settings/
.metadata/
.factorypath
.apt_generated/

# NetBeans
nbproject/private/
nbbuild/
nbdist/
.nb-gradle/

# Vim / Emacs / Sublime / Misc
*.swp
*.swo
*~
.*.sw?
*.sublime-workspace
*.sublime-project
.\#*
\#*\#

# AI assistants / agents
.claude/
.aider*
.cursor/

# Logs / temp
*.log
logs/
tmp/
temp/

# have to be delete
codestar-draft-design/
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"i18n-ally.localesPaths": [
"apps/frontend/messages"
],
"java.configuration.updateBuildConfiguration": "interactive"
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Codestar

Open-source & self-hosted e-learning platform
Open-source & self-hosted e-learning platform template to build yours easly.

## Backend

Expand Down
41 changes: 41 additions & 0 deletions apps/backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Maven
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
dependency-reduced-pom.xml
.flattened-pom.xml
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
buildNumber.properties

# Gradle (safety net)
.gradle/
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

# Java
*.class
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
*.ctxt
.mtj.tmp/
hs_err_pid*
replay_pid*

# Spring Boot
HELP.md
.springBeans

# Logs
*.log
4 changes: 2 additions & 2 deletions apps/backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Stage 1: Build
# Build
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app

Expand All @@ -9,7 +9,7 @@ RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests -B

# Stage 2: Runtime
# Runtime
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app

Expand Down
30 changes: 28 additions & 2 deletions apps/backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<artifactId>backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>backend</name>
<description>Demo project for Spring Boot</description>
<description>API backend for CodeStar</description>

<properties>
<java.version>17</java.version>
Expand All @@ -26,6 +26,11 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand All @@ -42,12 +47,33 @@
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>

<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
Expand All @@ -71,7 +97,7 @@
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
<version>2.7.0</version>
</dependency>

</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
@ConfigurationPropertiesScan
public class BackendApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.codestar.backend.config;

import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Positive;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties(prefix = "codestar.ai")
@Validated
public record AiProperties(
String apiUrl,
String apiKey,
String model,
@Positive int maxTokens,
@DecimalMin("0.0") @DecimalMax("2.0") double temperature,
@Positive int connectTimeoutSeconds,
@Positive int timeoutSeconds,
@Positive int rateLimitCapacity,
@Positive int rateLimitRefillPerMinute,
@Positive long rateLimitIdleTtlMinutes,
@Positive long rateLimitSweepMs
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.codestar.backend.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConfigurationProperties(prefix = "codestar.bootstrap.super-admin")
public record BootstrapProperties(
@DefaultValue("") String email,
@DefaultValue("") String password,
@DefaultValue("Super-admin") String displayName
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.codestar.backend.config;

import jakarta.validation.constraints.NotEmpty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import java.util.List;


@ConfigurationProperties(prefix = "codestar.cors")
@Validated
public record CorsProperties(
@NotEmpty List<String> allowedOrigins
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.codestar.backend.config;

import jakarta.validation.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;


@ConfigurationProperties(prefix = "codestar.instance")
@Validated
public record InstanceProperties(
// Path/URL to the branding instance.json file
@NotBlank String configPath
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.codestar.backend.config;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Positive;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;


@ConfigurationProperties(prefix = "jwt")
@Validated
public record JwtProperties(
@NotBlank String secret,
@Positive long expiration
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.codestar.backend.config;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Positive;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;


@ConfigurationProperties(prefix = "codestar.media")
@Validated
public record MediaProperties(
@NotBlank String storagePath,
@Positive long userQuotaMb,
@Positive long instanceQuotaMb,
@Valid RateLimit rateLimit
) {
public record RateLimit(
@Positive int capacity,
@Positive int refillPerMinute,
@Positive long idleTtlMinutes,
@Positive long sweepMs
) {}
}
Loading
Loading