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
33 changes: 33 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# EditorConfig — consistent formatting across editors and contributors
# https://editorconfig.org

root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{html,css}]
indent_size = 2

[*.js]
indent_size = 2

[*.{json,yml,yaml}]
indent_size = 2

[*.py]
indent_size = 4

[*.{r,R}]
indent_size = 2

[Makefile]
indent_style = tab
51 changes: 51 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Auto-detect text files and normalise line endings to LF
* text=auto eol=lf

# Explicitly declare text files
*.html text eol=lf
*.css text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.toml text eol=lf
*.xml text eol=lf
*.svg text eol=lf
*.txt text eol=lf
*.sh text eol=lf
*.py text eol=lf
*.r text eol=lf
*.R text eol=lf

# Windows-specific files keep CRLF
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf

# Binary files — no diff, no merge, no line-ending conversion
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.webp binary
*.avif binary
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary
*.otf binary
*.pdf binary
*.zip binary
*.gz binary
*.tar binary
*.mp4 binary
*.webm binary
*.mp3 binary
*.ogg binary

# Lock files — exact merge to prevent conflicts
package-lock.json merge=ours
yarn.lock merge=ours
42 changes: 42 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Commit message hook: enforce prefix convention from CONTRIBUTING.md
set -euo pipefail

MSG_FILE="$1"
MSG=$(head -1 "$MSG_FILE")

RED='\033[0;31m'
NC='\033[0m'

# Skip merge commits and fixup/squash commits
if echo "$MSG" | grep -qE '^(Merge|Revert|fixup!|squash!)'; then
exit 0
fi

# Allowed prefixes (from CONTRIBUTING.md)
PREFIXES="Add|Fix|Update|Translate|Docs|Refactor|Test|CI|Chore|Merge"

if ! echo "$MSG" | grep -qE "^(${PREFIXES}):"; then
echo -e "${RED}Invalid commit message format.${NC}"
echo ""
echo "Commit message must start with one of these prefixes:"
echo " Add: — New feature, course, or tool"
echo " Fix: — Bug fix or broken link"
echo " Update: — Improvement to existing content or code"
echo " Translate: — Translation work"
echo " Docs: — Documentation changes"
echo " Refactor: — Code restructuring (no behaviour change)"
echo " Test: — Adding or updating tests"
echo " CI: — CI/CD pipeline changes"
echo " Chore: — Maintenance (deps, configs, tooling)"
echo ""
echo "Example: Add: interactive Theory of Change lab"
echo ""
echo "Your message was: $MSG"
exit 1
fi

# Warn if subject line is too long
if [ ${#MSG} -gt 72 ]; then
echo -e "\033[0;33mWARNING:\033[0m Commit subject is ${#MSG} chars (recommended max: 72)"
fi
65 changes: 65 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Pre-commit hook: catch common mistakes before they're committed
set -euo pipefail

RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

echo "Running pre-commit checks..."

# 1. Block commits of sensitive files
SENSITIVE_PATTERNS=('.env' '.env.local' '.env.production' 'credentials.json' '*.pem' '*.key')
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)

for pattern in "${SENSITIVE_PATTERNS[@]}"; do
while IFS= read -r file; do
if [[ -n "$file" ]]; then
echo -e "${RED}BLOCKED:${NC} Refusing to commit sensitive file: $file"
echo "If this is intentional, use: git commit --no-verify"
exit 1
fi
done < <(echo "$STAGED_FILES" | grep -E "^${pattern//\*/.*}$" 2>/dev/null || true)
done

# 2. Check for debug/console statements in staged JS/TS/Python files
CODE_FILES=$(echo "$STAGED_FILES" | grep -E '\.(js|ts|py)$' || true)
if [ -n "$CODE_FILES" ]; then
ISSUES=0
while IFS= read -r file; do
if git diff --cached "$file" | grep -E '^\+.*console\.(log|debug|warn)\(' | grep -v '// keep' > /dev/null 2>&1; then
echo -e "${YELLOW}WARNING:${NC} console.log/debug/warn found in $file"
ISSUES=$((ISSUES + 1))
fi
if git diff --cached "$file" | grep -E '^\+.*(debugger|breakpoint\(\))' > /dev/null 2>&1; then
echo -e "${RED}BLOCKED:${NC} debugger statement found in $file"
exit 1
fi
done <<< "$CODE_FILES"
if [ $ISSUES -gt 0 ]; then
echo -e "${YELLOW}Found $ISSUES file(s) with console statements. Consider removing them.${NC}"
fi
fi

# 3. Check for merge conflict markers
if [ -n "$STAGED_FILES" ]; then
while IFS= read -r file; do
if [ -f "$file" ] && grep -rn '<<<<<<<\|=======\|>>>>>>>' "$file" > /dev/null 2>&1; then
echo -e "${RED}BLOCKED:${NC} Merge conflict markers found in $file"
exit 1
fi
done <<< "$STAGED_FILES"
fi

# 4. Warn on large files (> 500KB)
while IFS= read -r file; do
if [ -f "$file" ]; then
SIZE=$(wc -c < "$file")
if [ "$SIZE" -gt 512000 ]; then
SIZE_KB=$((SIZE / 1024))
echo -e "${YELLOW}WARNING:${NC} Large file (${SIZE_KB}KB): $file"
fi
fi
done <<< "$STAGED_FILES"

echo "Pre-commit checks passed."
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/content_issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: Content Issue
about: Report outdated, incorrect, or missing content
title: "[Content] "
labels: content
assignees: ''
---

**Page/Course affected**
Which page or course has the issue?

**What's wrong?**
Describe the content issue (outdated stat, broken citation, missing topic, etc.)

**Suggested correction**
If you know the correct information, please share it with a source/reference.
42 changes: 42 additions & 0 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Security Policy

## Supported Versions

| Version | Supported |
| ------- | --------- |
| Latest (main branch) | Yes |

## Reporting a Vulnerability

If you discover a security vulnerability in devdata-practice, please report it responsibly.

**Do NOT open a public GitHub issue for security vulnerabilities.**

Instead, please email **hello@impactmojo.in** with:

- A description of the vulnerability
- Steps to reproduce the issue
- Any potential impact
- Suggested fix (if you have one)

We will acknowledge your report within 48 hours and aim to release a fix within 7 days for critical issues.

## Scope

The following are in scope:

- Cross-site scripting (XSS) in any page
- Authentication or authorisation bypass
- Exposed secrets or credentials
- Insecure dependencies with known CVEs
- Open redirects

## Out of Scope

- Denial of service attacks
- Social engineering
- Issues in third-party services

## Recognition

We're happy to credit security researchers in our changelog. Let us know if you'd like to be acknowledged.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@ __pycache__/
dist/
build/
.DS_Store

# Added by git standards propagation
node_modules/
Thumbs.db
*.log
coverage/
.vscode/
.idea/
*.swp
19 changes: 19 additions & 0 deletions .gitmessage
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# <prefix>: <short summary in imperative mood, max 72 chars>
#
# Prefixes:
# Add: — New feature, course, or tool
# Fix: — Bug fix or broken link
# Update: — Improvement to existing content or code
# Translate: — Translation work
# Docs: — Documentation changes
# Refactor: — Code restructuring (no behaviour change)
# Test: — Adding or updating tests
# CI: — CI/CD pipeline changes
# Chore: — Maintenance (deps, configs, tooling)
#
# Example:
# Add: interactive Theory of Change lab
# Fix: broken nav dropdown on mobile Safari
#
# Body (optional): explain *why*, not *what* — the diff shows what changed.
# Wrap at 72 characters.