Skip to content
Closed
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
10 changes: 10 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
* @anyulled

# Documentation and Architecture
/ARCHITECTURE.md @anyulled
/SECURITY.md @anyulled
/docs/ @anyulled

# Core Configuration
/package.json @anyulled
/.github/workflows/ @anyulled
15 changes: 15 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Description

Please describe the changes in this PR. Include motivation, problem addressed, and details of the solution.

## Checklist

- [ ] Tests pass (Unit and E2E)
- [ ] Linter & Formatter pass (`npm run lint`, `npm run format:check`)
- [ ] SonarQube findings have been addressed
- [ ] No unhandled Promise rejections, `any` types eradicated
- [ ] Small Batch: This PR is focused and logically independent.

## Testing Performed

Please provide a brief output or description of the tests run to verify the change.
46 changes: 43 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,55 @@ updates:
schedule:
interval: "daily"
groups:
react:
eslint:
patterns:
- "react*"
- "@types/react*"
- "eslint*"
- "@eslint*"
- "@typescript-eslint*"
- "@next/eslint-plugin-next"
vercel:
patterns:
- "@vercel/*"
testing:
patterns:
- "@testing-library*"
- "cypress*"
- "jest*"
- "@stryker-mutator*"
- "@jazzer.js*"
- "ts-jest"
- "fast-check"
lint-and-format:
patterns:
- "stylelint*"
- "prettier"
- "husky"
- "lint-staged"
- "@commitlint*"
animations:
patterns:
- "framer-motion"
- "gsap"
- "aos"
- "@types/aos"
- "wowjs"
sliders-and-ui:
patterns:
- "swiper"
- "slick-carousel"
- "react-slick"
- "@types/react-slick"
react:
patterns:
- "react"
- "react-dom"
- "react-countup"
- "react-modal-video"
- "@types/react*"
typescript:
patterns:
- "typescript"
- "@types/*"
all-others:
patterns:
- "*"
Expand Down
14 changes: 11 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@ jobs:
node-version: 20
cache: "npm"
- name: Install Dependencies
run: npm ci
run: npm ci --legacy-peer-deps
- name: Lint
run: npm run lint
- name: Format Check
run: npm run format:check
- name: Security Audit
run: npm audit --audit-level=high || true
Comment on lines +25 to +26
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Make the security audit step actually gate high vulnerabilities.

Line 26 always exits successfully because of || true, so high-severity findings won’t block merges.

🔧 Suggested fix
-      - name: Security Audit
-        run: npm audit --audit-level=high || true
+      - name: Security Audit
+        run: npm audit --audit-level=high
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Security Audit
run: npm audit --audit-level=high || true
- name: Security Audit
run: npm audit --audit-level=high
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 25 - 26, The "Security Audit" CI step
currently uses the command "npm audit --audit-level=high || true" which forces a
successful exit; remove the "|| true" fallback so the step fails on
high-severity findings (i.e., run "npm audit --audit-level=high" or otherwise
ensure the step does not ignore non-zero exit codes) to make the Security Audit
gate block merges when high vulnerabilities are found.

- name: Docs Sync Check
run: npm run check:docs
- name: Link Checker
uses: lycheeverse/lychee-action@v2
with:
args: --offline --root-dir . --exclude-path node_modules '**/*.md'

test:
runs-on: ubuntu-latest
Expand All @@ -33,7 +41,7 @@ jobs:
node-version: 20
cache: "npm"
- name: Install Dependencies
run: npm ci
run: npm ci --legacy-peer-deps
- name: Unit Tests
run: npm run test:coverage
- name: Upload to Codecov
Expand All @@ -51,6 +59,6 @@ jobs:
node-version: 20
cache: "npm"
- name: Install Dependencies
run: npm ci
run: npm ci --legacy-peer-deps
- name: Build
run: npm run build
3 changes: 2 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ jobs:
cache: "npm"

- name: Install Dependencies
run: npm ci
run: npm ci --legacy-peer-deps

- name: Cypress Run
uses: cypress-io/github-action@v7
with:
install: false
build: npm run build
start: npm start
wait-on: "http://localhost:3000"
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: AI Harness Scorecard

on:
push:
branches: [main]
schedule:
- cron: "0 6 * * 1"

jobs:
scorecard:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- uses: markmishaev76/ai-harness-scorecard@v1
id: scorecard
- name: Commit badge and report
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add scorecard-badge.json scorecard-report.md
git diff --cached --quiet || git commit -m "chore: update scorecard badge and report"
git push
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,10 @@ dist
.DS_Store
next-env.d.ts

# PWA service worker (generated by @ducanh2912/next-pwa)
public/sw.js
public/sw.js.map
public/workbox-*.js
public/workbox-*.js.map
public/swe-worker-*.js
public/swe-worker-*.js.map
4 changes: 4 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit ${1}
2 changes: 1 addition & 1 deletion .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

npm test
npm run test:coverage
npm run build
20 changes: 20 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# AI Agent Instructions

This document provides system instructions for AI coding assistants working on the DevBcn project.

## Code Style & Constraints

- **Architectural Boundaries**: React Components must not import from `app/`. Data must flow down via props.
- **Typing**: Use strict TypeScript. Avoid `any` at all costs.
- **Error Handling Policy**: Avoid unhandled promise rejections. Do not use generic catch-all statements without logging or handling the error properly.
- **Comments**: Code must be self-documenting. DO NOT add inline comments explaining _what_ code does. Only explain _why_ non-obvious decisions were made.
- **Styling**: SCSS must be used. No Tailwind or CSS Modules.

## AI Usage Norms

- No unchecked AI-generated code should be pushed to main. All code must pass the test suite.
- Ensure code changes are manually reviewed as per branch protection rules.
- Agents must never bypass `pre-commit`, `commit-msg`, or `pre-push` Git hooks.
- Do not disable eslint rules.
- Check the build and tests always pass before completing a task.
- Check SonarQube findings and resolve them before claiming any task is done.
155 changes: 155 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Architecture

This document describes the high-level architecture of the DevBcn website.
If you want to familiarize yourself with the codebase, this is a good place to start.

## Bird's Eye View

A Next.js 16 App Router application serving the DevBcn conference website.
Static and multi-year: every past and current edition lives under `/{year}`.
Speaker, talk, and schedule data come from the **Sessionize API** at runtime.
Edition-specific configuration (dates, feature flags, sponsors) is defined in code.
Deployed to Vercel with PWA support via `@ducanh2912/next-pwa`.

```
Sessionize API ──► hooks/ ──► app/[year]/ pages
config/editions/ ─────────────────┘
```
Comment on lines +14 to +18
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language to the fenced code block.

Line 14 opens a fenced block without a language, which trips markdown linting (MD040).

Suggested fix
-```
+```text
 Sessionize API ──► hooks/ ──► app/[year]/ pages
                                   ▲
 config/editions/ ─────────────────┘
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.21.0)</summary>

[warning] 14-14: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @ARCHITECTURE.md around lines 14 - 18, In ARCHITECTURE.md update the fenced
code block that contains the ASCII diagram starting with "Sessionize API ──►
hooks/ ──► app/[year]/ pages" to include a language identifier (e.g. change the
opening totext) so the block is lint-friendly; locate the block around
that diagram and replace the fence accordingly.


</details>

<!-- fingerprinting:phantom:poseidon:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->


## Module Map

### `app/`

Next.js App Router routes. Two routing layers:

- **Top-level** (`app/(global)/`, `app/about/`, `app/blog/`, …): year-independent pages.
- **`app/[year]/`**: year-scoped pages (speakers, talks, schedule, sponsors, etc.).
Contains its own `layout.tsx` that resolves the edition config from the URL param.

The `app/[year]/@modal/` directory uses Next.js parallel routes for modal intercepts.

`app/layout.tsx` is the root layout: fonts, global CSS imports, analytics, PWA meta.

### `config/`

Static, compile-time configuration. Three sub-modules:

- **`config/editions/`**: Per-year config files (`2023.ts` … `2026.ts`) implementing
`EditionConfig`. Controls feature flags, dates, sponsor data, Sessionize URLs.
`CURRENT_EDITION` constant determines the default year.
- **`config/navigation/`**: Centralized nav links consumed by header and mobile menu.
- **`config/job-offers/`**: Job listing data.

**Constraint**: `config/` must remain pure data — no React, no side effects, no fetching.

### `hooks/`

Server-side data-fetching functions (despite the directory name, these are **not**
React hooks). Each wraps a Sessionize API endpoint with `react.cache()`:

- `useSpeakers.ts` → `/view/Speakers`
- `useTalks.ts` → `/view/Sessions`
- `useSchedule.ts` → `/view/GridSmart`

Types for Sessionize responses live in `hooks/types.ts`.

**Constraint**: these functions are designed for Server Components only. They use
`fetch` with `next: { revalidate: 3600 }` — do not call them from Client Components.

### `components/`

React components, organized by purpose:

- **`layout/`**: Shell components — header, footer, mobile menu, breadcrumb, speaker/talk
cards, filter bars. Most are Client Components (`'use client'`).
- **`elements/`**: Small interactive widgets — countdown, back-to-top, theme switch,
video player, track badges.
- **`sections/`**: Full page sections composed for home page variants (`home1/` … `home10/`),
FAQ, and venue.
- **`ui/`**: Generic UI primitives (Modal).
- **`speakers/`**, **`talks/`**, **`schedule/`**, **`slider/`**, **`skeletons/`**: Domain-specific
component groups.

**Constraint**: components must not import from `app/`. Data flows down from route
pages through props.

### `context/`

Client-side React Context. Currently only `ScheduleContext` — manages saved sessions
via `localStorage`. Provided by `ClientLayout` at the root.

**Constraint**: contexts are always Client Components. Keep them minimal to avoid
unnecessary re-renders.

### `lib/shared/`

Pure utility functions: markdown rendering, JSON-LD generation, analytics helpers,
slugification, speaker/talk filter logic.

**Constraint**: no React imports, no state, no side effects. Must be importable from
both server and client code.

### `styles/`

SCSS-based styling system:

- `main.scss`: entry point.
- `theme/`: design tokens and variables.
- `components/`: component-specific styles.
- `layout/`: structural layout styles.
- `utils/`: mixins and helpers.
- `vendor/`: third-party CSS (Bootstrap, AOS, Slick, etc.).

**Constraint**: no CSS Modules, no Tailwind. All styles flow through the SCSS pipeline.

### `types/`

Shared TypeScript interfaces for component props (`HeaderProps`, `BreadcrumbProps`,
`BackToTopProps`). Sessionize domain types live in `hooks/types.ts` instead.

### `team/`

Static team member data (`TeamMembers.ts`).

### `__tests__/`

Jest unit tests mirroring the source tree structure.
Cypress E2E tests live in `cypress/`.

## Cross-Cutting Concerns

### Multi-Year Support

The `[year]` dynamic segment is the backbone of the site. Each year's page resolves
its `EditionConfig` via `getEditionConfig(year)` and passes it (or derived data)
down through props. Navigation links are prefixed with the active year.

### External Data

All speaker, talk, and schedule data comes from Sessionize. The API URL is stored
per-edition in `config/editions/`. Data is cached at the `fetch` level
(`revalidate: 3600`) and at the React level (`cache()`).

### Quality Tooling

- **ESLint** (flat config) + **Prettier** + **Stylelint** enforced via Husky pre-commit hooks.
- **lint-staged** runs formatters and linters on staged files.
- Git hooks must never be bypassed.

## Invariants

1. `config/` is pure data — no React, no fetching, no side effects.
2. `hooks/` fetch functions are server-only — never call from Client Components.
3. Components never import from `app/` — data flows down via props.
4. Styles use SCSS exclusively — no CSS Modules, no Tailwind.
5. Every edition must implement the full `EditionConfig` interface.
6. Git hooks (pre-commit, commit-msg, pre-push) are never bypassed.

## Module Boundaries

- `components/` never depends on `app/`.
- `hooks/` never depends on `components/` or `app/`.
- `config/` never depends on any other workspace module.
- `styles/` never depends on any other workspace module.
- `lib/` never depends on `app/` or `components/`.
19 changes: 19 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Contributing

Thank you for contributing to DevBcn!

## Small Batch Enforcement

Please submit Pull Requests in small, cohesive batches. Do not submit monolithic PRs containing thousands of lines of changes, especially when AI coding assistants are used. Small PRs are easier to review and less likely to introduce subtle regressions.

## Git Hooks

Zero Tolerance: Never bypass git hooks (`--no-verify`). We focus on quality over speed.
All commits must successfully pass the pre-commit linters and tests.

## Code Standards

- Ensure 90% test coverage.
- Apply SOLID, DRY, KISS, and YAGNI principles.
- Follow the Law of Demeter and "Tell, Don't Ask" pattern.
- Fix any and all SonarQube issues before opening a PR.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# eventify nextjs
# Devbcn

# made by alithemes.com
[![AI Harness Scorecard](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fanyulled%2Fdevbcn-nextjs%2Frefs%2Fheads%2Fmain%2Fscorecard-badge.json)](scorecard-report.md)
Loading