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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ Run the entire stack (API + PostgreSQL DB) using Docker Compose:
docker compose --profile local up -d --build
## FOR PRODUCTION
docker compose --profile remote up -d --build

## FOR REBUILD WHILE DOCKER STILL RUNNING
docker compose --profile local up -d --build --force-recreate
```

- `-d`: Runs containers in the background (**detached mode**).
Expand Down
74 changes: 74 additions & 0 deletions alembic/versions/12d232b53016_add_chunks_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Add chunks tables

Revision ID: 12d232b53016
Revises: 526810671b5e
Create Date: 2026-02-28 05:35:17.727901

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlmodel


# revision identifiers, used by Alembic.
revision: str = '12d232b53016'
down_revision: Union[str, Sequence[str], None] = '526810671b5e'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('chunk_templates',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('name', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('template_code', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('description', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('chunks',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('template_id', sa.Uuid(), nullable=False),
sa.Column('title', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('difficulty', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['template_id'], ['chunk_templates.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('chunks_categories',
sa.Column('chunk_id', sa.Uuid(), nullable=False),
sa.Column('category_id', sa.Uuid(), nullable=False),
sa.ForeignKeyConstraint(['category_id'], ['categories.id'], ),
sa.ForeignKeyConstraint(['chunk_id'], ['chunks.id'], ),
sa.PrimaryKeyConstraint('chunk_id', 'category_id')
)
op.create_table('chunks_tags',
sa.Column('chunk_id', sa.Uuid(), nullable=False),
sa.Column('tag_id', sa.Uuid(), nullable=False),
sa.ForeignKeyConstraint(['chunk_id'], ['chunks.id'], ),
sa.ForeignKeyConstraint(['tag_id'], ['tags.id'], ),
sa.PrimaryKeyConstraint('chunk_id', 'tag_id')
)
op.create_table('snippets',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('snippet_id', sa.Uuid(), nullable=False),
sa.Column('placeholder_key', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('code_content', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.ForeignKeyConstraint(['snippet_id'], ['chunks.id'], ),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('snippets')
op.drop_table('chunks_tags')
op.drop_table('chunks_categories')
op.drop_table('chunks')
op.drop_table('chunk_templates')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Rename ChunkTestCase to Expectation

Revision ID: 195da80e49b0
Revises: bef4f254435d
Create Date: 2026-02-28 06:57:58.901505

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlmodel


# revision identifiers, used by Alembic.
revision: str = '195da80e49b0'
down_revision: Union[str, Sequence[str], None] = 'bef4f254435d'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
op.rename_table('chunk_test_cases', 'expectations')

def downgrade() -> None:
"""Downgrade schema."""
op.rename_table('expectations', 'chunk_test_cases')
35 changes: 35 additions & 0 deletions alembic/versions/7d97a9392f2b_add_chunk_testcase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Add chunk testcase

Revision ID: 7d97a9392f2b
Revises: 12d232b53016
Create Date: 2026-02-28 06:33:32.364820

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlmodel


# revision identifiers, used by Alembic.
revision: str = '7d97a9392f2b'
down_revision: Union[str, Sequence[str], None] = '12d232b53016'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
op.add_column('chunks', sa.Column('test_case_input', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
op.add_column('chunks', sa.Column('test_case_output', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
# Make them not nullable if required, but default=""
op.execute("UPDATE chunks SET test_case_input = '', test_case_output = ''")
op.alter_column('chunks', 'test_case_input', nullable=False)
op.alter_column('chunks', 'test_case_output', nullable=False)


def downgrade() -> None:
"""Downgrade schema."""
op.drop_column('chunks', 'test_case_output')
op.drop_column('chunks', 'test_case_input')
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Redesign chunks for multi-language support

Revision ID: 922b6da97d7e
Revises: 195da80e49b0
Create Date: 2026-02-28 07:21:08.426698

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlmodel


# revision identifiers, used by Alembic.
revision: str = '922b6da97d7e'
down_revision: Union[str, Sequence[str], None] = '195da80e49b0'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# 1. Update chunk_templates
op.add_column('chunk_templates', sa.Column('chunk_id', sa.UUID(), nullable=True))
op.add_column('chunk_templates', sa.Column('language', sa.String(), nullable=True))
op.create_foreign_key('fk_chunk_templates_chunk_id', 'chunk_templates', 'chunks', ['chunk_id'], ['id'])

# 2. Update chunks
op.drop_constraint('chunks_template_id_fkey', 'chunks', type_='foreignkey') # Might name differ, usually table_column_fkey
op.drop_column('chunks', 'template_id')

# 3. Update snippets
op.add_column('snippets', sa.Column('template_id', sa.UUID(), nullable=True))
op.create_foreign_key('fk_snippets_template_id', 'snippets', 'chunk_templates', ['template_id'], ['id'])
op.drop_constraint('snippets_snippet_id_fkey', 'snippets', type_='foreignkey')
op.drop_column('snippets', 'snippet_id')

def downgrade() -> None:
"""Downgrade schema."""
# Reverse snippets
op.add_column('snippets', sa.Column('snippet_id', sa.UUID(), nullable=True))
op.create_foreign_key('snippets_snippet_id_fkey', 'snippets', 'chunks', ['snippet_id'], ['id'])
op.drop_constraint('fk_snippets_template_id', 'snippets', type_='foreignkey')
op.drop_column('snippets', 'template_id')

# Reverse chunks
op.add_column('chunks', sa.Column('template_id', sa.UUID(), nullable=True))
op.create_foreign_key('chunks_template_id_fkey', 'chunks', 'chunk_templates', ['template_id'], ['id'])

# Reverse chunk_templates
op.drop_constraint('fk_chunk_templates_chunk_id', 'chunk_templates', type_='foreignkey')
op.drop_column('chunk_templates', 'language')
op.drop_column('chunk_templates', 'chunk_id')
44 changes: 44 additions & 0 deletions alembic/versions/bef4f254435d_add_chunk_test_cases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Add chunk test cases

Revision ID: bef4f254435d
Revises: 7d97a9392f2b
Create Date: 2026-02-28 06:44:40.393036

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import sqlmodel


# revision identifiers, used by Alembic.
revision: str = 'bef4f254435d'
down_revision: Union[str, Sequence[str], None] = '7d97a9392f2b'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('chunk_test_cases',
sa.Column('id', sa.Uuid(), nullable=False),
sa.Column('chunk_id', sa.Uuid(), nullable=False),
sa.Column('input', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column('output', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.ForeignKeyConstraint(['chunk_id'], ['chunks.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.drop_column('chunks', 'test_case_input')
op.drop_column('chunks', 'test_case_output')
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('chunks', sa.Column('test_case_output', sa.VARCHAR(), autoincrement=False, nullable=False))
op.add_column('chunks', sa.Column('test_case_input', sa.VARCHAR(), autoincrement=False, nullable=False))
op.drop_table('chunk_test_cases')
# ### end Alembic commands ###
3 changes: 3 additions & 0 deletions bruno/environments/code-exec.bru
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
vars {
base_url: http://localhost:3000
}
vars:secret [
code-exec-url,
zip-path
Expand Down
28 changes: 28 additions & 0 deletions bruno/local/Chunk/Execute Complex JS Chunk.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
meta {
name: Execute Complex JS Chunk
type: http
seq: 6
}

post {
url: http://localhost:3000/chunk/execute/4c80ce4e-38e0-42ba-a72c-e3103dcaa766?lang=javascript
body: json
auth: none
}

params:query {
lang: javascript
}

body:json {
{
"snippets": {
"imports": "// No imports needed",
"setup": "const OFFSET = 100;\nfunction getOffset() { return OFFSET; }",
"args": "dataList, multiplier",
"validation": "if (!Array.isArray(dataList)) return null;",
"logic": "const result = dataList.map(x => utility(x) * multiplier + getOffset());\nreturn result;",
"test": "const res = solution([1, 2, 3], 5); console.log('[' + res.join(', ') + ']');"
}
}
}
28 changes: 28 additions & 0 deletions bruno/local/Chunk/Execute Complex Python Chunk.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
meta {
name: Execute Complex Python Chunk
type: http
seq: 5
}

post {
url: http://localhost:3000/chunk/execute/4c80ce4e-38e0-42ba-a72c-e3103dcaa766?lang=python
body: json
auth: none
}

params:query {
lang: python
}

body:json {
{
"snippets": {
"imports": "import math",
"setup": "OFFSET = 100\ndef get_offset(): return OFFSET",
"args": "data_list, multiplier",
"validation": "if not isinstance(data_list, list): return None",
"logic": "result = [utility(x) * multiplier + get_offset() for x in data_list]\nreturn result",
"test": "print(solution([1, 2, 3], 5))"
}
}
}
23 changes: 23 additions & 0 deletions bruno/local/Chunk/Execute JS Chunk.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
meta {
name: Execute JS Chunk
type: http
seq: 5
}

post {
url: http://localhost:3000/chunk/execute/9cb40096-ac06-4294-8d29-835eb30bfdce?lang=javascript
body: json
auth: none
}

query {
lang: javascript
}

body:json {
{
"snippets": {
"logic": "return x * y;"
}
}
}
23 changes: 23 additions & 0 deletions bruno/local/Chunk/Execute Python Chunk.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
meta {
name: Execute Python Chunk
type: http
seq: 4
}

post {
url: http://localhost:3000/chunk/execute/22e04d50-3aea-43ac-9a89-32daea0cc9f8?lang=python
body: json
auth: none
}

params:query {
lang: python
}

body:json {
{
"snippets": {
"logic": "return x * y"
}
}
}
17 changes: 17 additions & 0 deletions bruno/local/Chunk/Get All Chunks.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
meta {
name: Get All Chunks
type: http
seq: 1
}

get {
url: http://localhost:3000/chunk/?page=1&limit=10&lang=python
body: none
auth: none
}

query {
page: 1
limit: 10
lang: python
}
15 changes: 15 additions & 0 deletions bruno/local/Chunk/Get Chunk Details.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
meta {
name: Get Chunk Details
type: http
seq: 3
}

get {
url: http://localhost:3000/chunk/9cb40096-ac06-4294-8d29-835eb30bfdce?lang=python
body: none
auth: none
}

query {
lang: python
}
Loading