Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 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
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@
from ee.src.models.extended.deprecated_models import DeprecatedOrganizationDB
from ee.src.dbs.postgres.subscriptions.dbes import SubscriptionDBE
from ee.src.dbs.postgres.meters.dbes import MeterDBE
from ee.src.core.subscriptions.types import FREE_PLAN
from ee.src.core.entitlements.types import Gauge

# Point-in-time literal; the runtime free-plan slug is now resolved via
# `ee.src.core.subscriptions.settings.get_free_plan()`. Operators running
# with a custom `AGENTA_ACCESS_PLANS` set must either keep this slug in
# the effective plan set or declare a `"free": true` entry in
# `AGENTA_BILLING_PRICING`. Startup validation in `settings.py` fails fast
# when neither condition is met.
FREE_PLAN = "cloud_v0_hobby"

stripe.api_key = env.stripe.api_key

log = get_module_logger(__name__)
Expand Down Expand Up @@ -143,7 +150,7 @@ def upgrade() -> None:
organization_id=organization_id,
subscription_id=subscription_id,
customer_id=customer_id,
plan=plan.value,
plan=plan,
active=active,
anchor=anchor,
)
Expand All @@ -158,7 +165,7 @@ def upgrade() -> None:
.values(
subscription_id=subscription_id,
customer_id=customer_id,
plan=plan.value,
plan=plan,
active=active,
anchor=anchor,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Unify organization_members.role 'member' to 'viewer'

Aligns the organization scope with workspace/project scopes on a single
least-permission role slug. The runtime access-controls layer
(`ee.src.core.entitlements.controls`) treats `viewer` as the per-scope
minima for every scope; this migration brings stored data and the column
default in line with that.

- Rewrites every row with role='member' to role='viewer'.
- Changes the column server default from 'member' to 'viewer'.

The downgrade reverses both, restoring the previous behavior.

Revision ID: a1b2c3d4e5f7
Revises: e6f7a8b9c0d1
Create Date: 2026-05-13 00:00:00.000000
"""

from typing import Sequence, Union

from alembic import op
from sqlalchemy import text


revision: str = "a1b2c3d4e5f7"
down_revision: Union[str, None] = "e6f7a8b9c0d1"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
conn = op.get_bind()

conn.execute(
text("UPDATE organization_members SET role = 'viewer' WHERE role = 'member'")
)

op.alter_column(
"organization_members",
"role",
server_default="viewer",
existing_type=None,
existing_nullable=False,
)


def downgrade() -> None:
conn = op.get_bind()

op.alter_column(
"organization_members",
"role",
server_default="member",
existing_type=None,
existing_nullable=False,
)

conn.execute(
text("UPDATE organization_members SET role = 'member' WHERE role = 'viewer'")
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,20 @@
import uuid_utils.compat as uuid

from oss.src.utils.env import env
from ee.src.core.subscriptions.types import FREE_PLAN
from sqlalchemy.dialects import postgresql

# Point-in-time literal; the runtime free-plan slug is now resolved via
# `ee.src.core.subscriptions.settings.get_free_plan()`.
#
# Operators running this migration MUST either:
# 1. keep `cloud_v0_hobby` in their effective `AGENTA_ACCESS_PLANS` set, or
# 2. set one entry of `AGENTA_BILLING_PRICING` to `"free": true` so
# `get_free_plan()` resolves without falling back to this literal.
#
# `settings._build_settings()` enforces this at startup; mismatches fail
# loudly rather than silently writing an unknown plan slug.
FREE_PLAN = "cloud_v0_hobby"

# revision identifiers, used by Alembic.
revision: str = "a9f3e8b7c5d1"
down_revision: Union[str, None] = "12d23a8f7dde"
Expand Down Expand Up @@ -402,7 +413,7 @@ def _constraint_exists(constraint_name: str) -> bool:
WHERE s.organization_id = o.id
)
"""),
{"plan": FREE_PLAN.value},
{"plan": FREE_PLAN},
)

# Step 13: Ensure any remaining orgs have flags set
Expand Down
10 changes: 6 additions & 4 deletions api/ee/docker/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ COPY ./ee/src/crons/meters.sh /meters.sh
COPY ./ee/src/crons/meters.txt /etc/cron.d/meters-cron
COPY ./ee/src/crons/spans.sh /spans.sh
COPY ./ee/src/crons/spans.txt /etc/cron.d/spans-cron
COPY ./ee/src/crons/events.sh /events.sh
COPY ./ee/src/crons/events.txt /etc/cron.d/events-cron

RUN chmod +x /queries.sh /meters.sh /spans.sh \
&& chmod 0644 /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron \
&& for f in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron; do sed -i -e '$a\' "$f"; done \
&& cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron \
RUN chmod +x /queries.sh /meters.sh /spans.sh /events.sh \
&& chmod 0644 /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron \
&& for f in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron; do sed -i -e '$a\' "$f"; done \
&& cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron \
| sed -E 's/^(([^[:space:]]+[[:space:]]+){5})root[[:space:]]+/\1/' \
| sed 's| >> /proc/1/fd/1 2>&1||' > /app/crontab \
&& chown agenta:agenta /app/crontab
Expand Down
6 changes: 4 additions & 2 deletions api/ee/docker/Dockerfile.gh
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ COPY --chmod=755 ./ee/src/crons/meters.sh /meters.sh
COPY --chmod=644 ./ee/src/crons/meters.txt /etc/cron.d/meters-cron
COPY --chmod=755 ./ee/src/crons/spans.sh /spans.sh
COPY --chmod=644 ./ee/src/crons/spans.txt /etc/cron.d/spans-cron
COPY --chmod=755 ./ee/src/crons/events.sh /events.sh
COPY --chmod=644 ./ee/src/crons/events.txt /etc/cron.d/events-cron

# Copy dependencies from builder
COPY --from=builder /opt/venv /opt/venv
Expand All @@ -117,10 +119,10 @@ COPY --chown=agenta:agenta --from=builder /clients/python /clients/python

# Generate supercronic-compatible crontab (strip user field and /proc redirects)
RUN set -eux; \
for cron_file in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron; do \
for cron_file in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron; do \
sed -i -e '$a\' "${cron_file}"; \
done; \
cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron \
cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron \
| sed -E 's/^(([^[:space:]]+[[:space:]]+){5})root[[:space:]]+/\1/' \
| sed 's| >> /proc/1/fd/1 2>&1||' > /app/crontab && \
chown agenta:agenta /app/crontab
Expand Down
Loading