MiniStack v1.1.2 — Cognito, EC2, EMR, 656 Tests, and Zero Docker Leaks

We just shipped MiniStack v1.1.2. This is the biggest release since the initial launch — full Amazon Cognito support, partial EC2, EMR, a complete test suite overhaul, and a pile of infrastructure fixes that make running MiniStack day-to-day significantly cleaner.

If you’re not familiar: MiniStack is a free, open-source local AWS emulator. One port, no account, no license key. A drop-in replacement for LocalStack — which moved its core services behind a paid plan.

What’s new in v1.1.0

Amazon Cognito — full emulation

This was the most requested feature since launch. v1.1.0 ships complete Cognito support across both planes:

User Pools (cognito-idp)

  • Full user lifecycle: SignUp, ConfirmSignUp, AdminCreateUser, AdminDeleteUser, AdminGetUser, ListUsers
  • Auth flows: USER_PASSWORD_AUTH, ADMIN_USER_PASSWORD_AUTH, REFRESH_TOKEN_AUTH, USER_SRP_AUTH (returns PASSWORD_VERIFIER challenge)
  • FORCE_CHANGE_PASSWORD challenge on first login
  • Self-service: ForgotPassword, ConfirmForgotPassword, ChangePassword, GetUser, DeleteUser
  • Groups, domains, MFA config, tags — all covered

Identity Pools (cognito-identity)

  • CreateIdentityPool, GetId, GetCredentialsForIdentity, GetOpenIdToken
  • SetIdentityPoolRoles, GetIdentityPoolRoles
  • Federated identity: MergeDeveloperIdentities, UnlinkIdentity

OAuth2

  • POST /oauth2/token — client_credentials flow, returns stub Bearer token

Stub JWTs are structurally valid base64url tokens — they pass format checks in most SDKs without needing real crypto.

import boto3

idp = boto3.client("cognito-idp", endpoint_url="http://localhost:4566",
                   aws_access_key_id="test", aws_secret_access_key="test",
                   region_name="us-east-1")

# Create a pool
pool = idp.create_user_pool(PoolName="my-app")
pool_id = pool["UserPool"]["Id"]

# Sign up a user
idp.sign_up(
    ClientId="local",
    Username="[email protected]",
    Password="Password123!",
    UserAttributes=[{"Name": "email", "Value": "[email protected]"}],
)

# Confirm and authenticate
idp.admin_confirm_sign_up(UserPoolId=pool_id, Username="[email protected]")
resp = idp.initiate_auth(
    AuthFlow="USER_PASSWORD_AUTH",
    AuthParameters={"USERNAME": "[email protected]", "PASSWORD": "Password123!"},
    ClientId="local",
)
print(resp["AuthenticationResult"]["AccessToken"])

644 tests — one file, all passing

We merged a separate QA test file into the main suite and fixed every test bug we found along the way:

  • test_s3_list_v1_marker_pagination — NextMarker only returned when Delimiter is set (AWS spec)
  • test_iam_inline_user_policy — boto3 deserialises PolicyDocument as a dict, not a string
  • test_kinesis_at_timestamp_iterator — boto3 already returns Data as bytes, no need to base64-decode
  • test_rds_snapshot_crud / test_rds_deletion_protection — added finally cleanup so containers are deleted after each test

644 tests across all 25 services. Single file. All passing.

Docker volume leak — fixed

This one was subtle. Every RDS (CreateDBInstance) and ElastiCache (CreateCacheCluster) call spins up a real Docker container. The postgres and mysql images declare VOLUME /var/lib/postgresql/data — so Docker was creating an anonymous volume for every container, even after the container was removed.

After 20 test runs: 30+ dangling volumes, 600MB+ of wasted space.

Two fixes:

  1. tmpfs on containers.run() — postgres/mysql data lives in container RAM. No volume created.
  2. container.remove(v=True) in reset() — volumes are removed with the container.
Before: 32 dangling volumes after 3 test runs
After:  2 volumes total (ministack + redis, always)

Clean up what you already have:

make purge

make purge — safe cleanup

purge: stop-compose
    docker rm -f $(docker ps -aq --filter "label=ministack") 2>/dev/null || true
    docker volume prune -f
    rm -rf ./data/s3/*

Every container MiniStack spins up is labelled ministack=true. The purge target uses that label — it won’t touch your other Redis, Postgres, or MySQL containers.

Bug fixes

  • Lambda GetFunctionConcurrency — was returning 404 after DeleteFunctionConcurrency. Now returns {} matching AWS behaviour
  • ElastiCache ModifyCacheParameterGroup — parameter key format was wrong (member vs ParameterNameValue). Modified params were silently ignored
  • RDS ModifyDBInstance — DeletionProtection=False with ApplyImmediately=True now correctly applies immediately
  • Cognito GetCredentialsForIdentity — response field is SecretKey (correct boto3 wire name)
  • Port conflict on pip install — ministack now prints a clear error if port 4566 is already in use instead of a raw uvicorn traceback

AWS CLI docs fix

A user reported credentials failing. The README was showing aws configure --profile local but then omitting --profile local from the example commands. Fixed — two working options now documented:

Option A — environment variables

export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1

aws --endpoint-url=http://localhost:4566 s3 mb s3://my-bucket

Option B — named profile

aws configure --profile local
# Access Key: test / Secret: test / Region: us-east-1

aws --profile local --endpoint-url=http://localhost:4566 s3 mb s3://my-bucket

Get it

# PyPI
pip install --upgrade ministack

# Docker
docker pull nahuelnucera/ministack:latest
docker compose up -d

GitHub: github.com/Nahuel990/ministack

25 AWS services. Free. MIT licensed. No account required.

What’s next

  • SFN Activities (CreateActivity, GetActivityTask) — already requested
  • State persistence for Secrets Manager, SSM, DynamoDB — PERSIST_STATE=1 currently only covers API Gateway
  • ACM — last item on the original roadmap

Issues and PRs welcome.

Foggy Odoo Bridge: Governed MCP Access to Odoo Data with Permission Preservation

I just open-sourced Foggy Odoo Bridge.

It is an Odoo addon that gives AI clients governed MCP access to Odoo data while preserving Odoo permission rules.

What it does

Most “AI + ERP” demos stop at connectivity. Foggy Odoo Bridge focuses on governed access instead — it keeps authentication, model visibility, and row-level rules inside Odoo before the query reaches the engine.

Highlights

  • API-key auth from Odoo
  • ir.model.access based model visibility
  • ir.rule conversion into query filters before execution
  • Multi-company isolation
  • Built-in semantic models for common Odoo objects
  • Built-in AI Chat inside Odoo
  • Support for embedded Python engine or external Foggy Python / Java services

Deployment Options

  • Embedded Python engine inside Odoo
  • External Foggy Python service
  • External Foggy Java service

Dependency Notes

If you only use it as a standalone MCP service, you do not need openai or anthropic in the Odoo environment. Those SDKs are only optional dependencies for the built-in AI Chat feature.

Repo: https://github.com/foggy-projects/foggy-odoo-bridge

The Ultimate Guide to Building Enterprise Micro-Frontends with Angular 21 & Native Federation

Introduction

Micro-Frontend (MFE) architecture is no longer a “luxury” for big tech—it’s a necessity for enterprise teams that need to scale. But in 2026, the way we build them has changed. If you’re still relying on heavy Webpack configurations, you’re already behind.

In this guide, I’ll show you how to build a production-ready MFE system using Angular 21 and Native Federation.

Why Native Federation?

Standard Module Federation is tied to Webpack. Native Federation is framework-agnostic and works natively with Vite and esbuild.

•
Speed: 10x faster builds.

•
Future-Proof: No more Webpack version hell.

•
Simplicity: Uses standard browser features (Import Maps).

The 3 Pillars of Enterprise MFEs

  1. The Shell (The Orchestrator)

The Shell isn’t just a wrapper; it’s the brain. It handles:

•
Authentication: Centralized JWT handling.

•
Routing: Dynamic loading of remote modules.

•
Shared State: Using NgRx Signals for lightweight, reactive data sharing.

  1. The Remotes (The Features)

Each remote app (Auth, Dashboard, Settings) should be independently deployable. If your Dashboard team breaks something, your Auth app should still work.

  1. The Shared Library

Don’t duplicate your UI components. Use a shared library (@mfe/shared) for your Tailwind configurations, Angular Material themes, and common utilities.

The “Hidden” Challenge: RTL & Multi-language

Most MFE tutorials ignore the Middle Eastern market. If you’re building for clients in the UAE or KSA, Arabic RTL support isn’t optional.

•
The Problem: How do you sync the RTL direction across 5 different micro-apps instantly?

•
The Solution: A centralized DirectionService in the Shell that propagates state via Import Maps.

🚀 Stop Reinventing the Wheel

Building this architecture from scratch takes 100+ hours of configuration, testing, and debugging.

I’ve already done the hard work for you. I built NgMFE, a production-ready boilerplate that includes:

•
✅ Angular 21 + Native Federation

•
✅ Full JWT Auth & Route Guards

•
✅ Native Arabic RTL Support

•
✅ CI/CD with GitHub Actions

Save weeks of development and launch your enterprise app today.

👉 Get the NgMFE Starter Kit on Gumroad

https://mhmoudashour.gumroad.com/l/hdditr

🔴 View the Live Demo

https://ng-mfe-shell.vercel.app/auth

Conclusion

Micro-frontends are powerful, but only if the foundation is solid. Don’t get stuck in “configuration hell.” Focus on building features, not architecture.

Have questions about Native Federation? Drop a comment below!

5 Tanda Bisnis Kamu Sudah Butuh Sistem Kasir Digital (POS)

Tidak semua bisnis langsung membutuhkan sistem kasir digital. Namun, ada tanda-tanda tertentu yang menunjukkan bahwa bisnis kamu sudah saatnya beralih ke sistem yang lebih modern.

Jika kamu mulai mengalami hal-hal berikut, mungkin ini saat yang tepat untuk upgrade.

📈 1. Transaksi Semakin Banyak

Seiring berkembangnya bisnis, jumlah transaksi akan meningkat.

Jika kamu masih menggunakan pencatatan manual, proses ini akan menjadi:

  • Lebih lambat
  • Lebih rawan kesalahan
  • Sulit dikontrol saat jam ramai

😵 2. Sering Terjadi Kesalahan Perhitungan

Kesalahan seperti:

  • Salah total
  • Salah harga
  • Salah kembalian

Mungkin terlihat kecil, tapi jika terjadi terus-menerus bisa berdampak pada keuangan bisnis.

📦 3. Stok Barang Tidak Akurat

Masalah yang sering terjadi:

  • Barang tercatat ada, tapi ternyata habis
  • Stok tidak pernah di-update
  • Sulit melacak keluar-masuk barang

Ini bisa menyebabkan kehilangan penjualan atau overstock.

🕒 4. Antrian Pelanggan Mulai Panjang

Proses transaksi manual biasanya memakan waktu lebih lama.

Akibatnya:

  • Pelanggan harus menunggu
  • Pengalaman belanja menurun
  • Potensi kehilangan pelanggan

📊 5. Tidak Punya Data Penjualan yang Jelas

Tanpa sistem digital, kamu mungkin kesulitan menjawab:

  • Produk apa yang paling laris?
  • Kapan waktu penjualan tertinggi?
  • Berapa total omzet harian?

Tanpa data, keputusan bisnis hanya berdasarkan perkiraan.

💡 Kenapa Sistem POS Menjadi Solusi?

Sistem POS membantu bisnis dengan cara:

  • Mempercepat proses transaksi
  • Mengurangi kesalahan pencatatan
  • Mengelola stok secara otomatis
  • Menyediakan laporan penjualan real-time

🧠 Insight

Banyak bisnis tidak sadar bahwa masalah kecil yang terjadi setiap hari sebenarnya adalah tanda bahwa sistem mereka sudah tidak efisien.

Menggunakan sistem yang tepat bukan hanya mempermudah kerja, tapi juga meningkatkan kualitas operasional bisnis.

🎯 Kesimpulan

Jika bisnis kamu mengalami beberapa tanda di atas, itu berarti kamu sudah siap untuk beralih ke sistem kasir digital.

Dengan sistem yang lebih terstruktur, bisnis bisa berjalan lebih cepat, akurat, dan scalable.

Expo app : RedirectTo field with Supabase Auth always set to localhost

You are building an Expo Mobile app with Supabase as a backend?

You have correctly set the redirect url to exp:///auth/callback** in the URL Configuration of Supabase Auth and want to try your flow on Expo Go?

If you keep seeing localhost as the redirectTo address in the reset password link set by email, here is the fix:

npx expo start --tunnel

I shipped v7. Nobody showed up. Here’s my honest breakdown.

I shipped FireChat v7 last week.

Real AES-256-GCM encryption. Messages that disappear when everyone leaves. View-once media that actually deletes from storage. Push notifications that work across devices. Song sharing. A PWA that installs on your phone. Seven rewrites worth of lessons baked in.

And still. Nobody showed up.

7 views in 7 days.

That’s not low traction. That’s digital silence.

So I stopped blaming “marketing”

Nobody owes me users. Not because I built something. Not because I spent six months on it. Not because I think it’s genuinely good.

People only care about one thing — why should I use this instead of everything else?

And honestly? I never answered that loudly enough.

FireChat exists because my friend’s sister kept reading our WhatsApp chats. I wanted a place where conversations are locked behind a passphrase, encrypted on your device, and gone the moment everyone leaves. No history. No logs. Nothing to scroll through on someone else’s unlocked phone.

That’s a real reason. I just never led with it.

What FireChat actually is

  • Sessions are ephemeral — everything disappears when the last person leaves
  • Messages are AES-256-GCM encrypted client-side before touching any server
  • Sessions lock behind an identifier passphrase — even if someone gets the invite link, they’re not getting in without the key
  • View-once images and videos — tap to view once, then it’s gone
  • Push notifications when you get invited, even with the app closed
  • Installable PWA — lives on your home screen like a native app
  • Every user gets a public profile page with their vibe and their song

This isn’t a weekend clone. This is six months of real decisions about encryption, ephemerality, and what it means to build something that actually respects the people using it.

My brutally honest guesses for why nobody’s here

  • Zero distribution. I have no audience. I built and shipped into the void.
  • It looks like “just another chat app” from the outside. The differentiation isn’t visible until you’re inside.
  • The people who need it most don’t know it exists.
  • I’ve been building. I haven’t been telling the story.

What I’m actually asking

Try it. Break it. Tell me why you wouldn’t use it. Tell me what would make you actually open it over WhatsApp or Discord or Signal.

No “nice project bro.” Real feedback only.

fyrechatz.vercel.app

Building is the easy part. Getting people to care is the whole game. And I’m just figuring that out.

Automating Your Studio: The Dynamic Student Profile

You know the feeling. The lesson ends, the student leaves, and you’re left staring at a blank page, trying to recall every detail to write meaningful notes and a custom practice plan. It’s time-consuming and mentally draining. The solution lies not in working harder, but in leveraging AI to build a Dynamic Student Profile.

The Core Principle: Structured Data In, Intelligent Insight Out

The magic isn’t in asking AI to invent something new each week. It’s in providing it with a consistent, structured framework of your professional observations. By feeding AI standardized data—like your specific “Challenge Codes” (#rhythm, #intonation) and “Practice Quality Descriptors”—it can transform raw notes into actionable insights and predictive tracking.

Think of your chosen digital hub (like Notion or Airtable) as the central brain. Here, you store each student’s “Assigned Practice,” “Skills Focus” from your Skills Tree, and “Repertoire Status.” The AI uses this historical data combined with your latest lesson notes to generate a coherent “Post-Lesson Summary” and a tailored “Primary Focus for Practice.”

See It in Action

After a violin lesson, you input notes mentioning “#intonation” in a specific exercise and “Lyrical Phrasing Emerging” in a piece. The AI references the student’s profile, recognizes a recurring intonation challenge, and automatically suggests targeted exercises for the next practice plan while highlighting the positive phrasing development.

Three Steps to Implement

  1. Select and Structure Your Hub. Choose a flexible tool like Notion to act as your central database. Build your template there, incorporating your standardized observation language and data points.
  2. Configure Your Dashboard. Create a “Week Ahead” view that surfaces key data: “Students Needing Attention,” those approaching milestones, and “Group Trends” across your studio.
  3. Iterate on the Output. Review the AI-generated notes and plans. Refine your template and inputs to ensure the outputs are accurate and increasingly valuable, automating both milestone tracking and pattern identification.

By implementing a Dynamic Student Profile, you shift from manual note-taking to automated insight generation. You gain a system that tracks progress, predicts plateaus, and personalizes practice—freeing you to focus on the art of teaching itself.

I Automated My Upwork Proposals With AI — Here’s the Template (Free)

I got tired of writing Upwork proposals from scratch every time. So I built a template system.

5 templates. Each one optimized for a specific type of AI consulting job. Copy the template, fill in the brackets, submit.

The Problem

Writing proposals takes 15-30 minutes each. Most get ignored. The ones that get responses have a pattern — they’re specific, they show relevant experience, and they’re short.

So I reverse-engineered what works and made templates.

The 5 Templates

1. MCP / AI Security Audit

For jobs mentioning: security, OWASP, MCP, compliance, vulnerability assessment.

Key hook: “I’ve built 17 production MCP servers and published a security checklist based on OWASP Agentic AI Top 10.”

2. Multi-Agent / AI Architecture

For jobs mentioning: AI agents, orchestration, distributed systems, multi-agent.

Key hook: “My production platform runs 9 coordinated services across 14 cloud providers.”

3. Claude / Anthropic Integration

For jobs mentioning: Claude, Anthropic, prompt engineering, Claude Code.

Key hook: “250+ skills, 35 agents, 17 MCP integrations in production.”

4. RAG / Knowledge Graph

For jobs mentioning: RAG, retrieval, vector search, embeddings, knowledge graph.

Key hook: “Production A-RAG system with 5,600+ entities, BM25 + semantic + causal search.”

5. General AI/LLM

For everything else: chatbots, automation, GPT integration.

Key hook: “9 coordinated AI services running 24/7 with 14 cloud providers.”

The Scoring System

Each template includes a scoring guide — match keywords from the job description to pick the right template:

Job keywords Template
security, audit, OWASP #1
agent, orchestration #2
Claude, Anthropic #3
RAG, knowledge graph #4
AI, LLM, chatbot #5

Why This Works

  1. Specificity — Each template includes concrete numbers (9 services, 14 providers, 5,600+ entities) instead of generic claims
  2. Brevity — All templates are under 150 words
  3. Social proof — Links to portfolio, GitHub, published research
  4. Call to action — Ends with availability and rate, not a question

Get the Templates

The full template pack (all 5 templates + scoring guide + customization tips) is available for free.

If it saves you time, consider supporting the project — I’m building an open-source distributed AGI platform with 9 coordinated services.

My Setup

I built these templates as part of a larger system — a distributed AGI platform that runs 9 coordinated AI services. The same system that generates these proposals also:

  • Benchmarks itself every 30 minutes
  • Identifies its own weaknesses
  • Generates improvement hypotheses
  • Runs experiments to test them

You can see it live at yedanyagami.cc, including real-time fleet status.

If you’re a freelance AI developer, these templates will save you hours. Copy them, customize them, iterate on what works.

And if you want to see how the system behind them works — check out the interactive terminal on my site. Type services to see what’s running.

Directus Auth out of the Box — Registration, Login, Email Verification and Password Reset

One of the things I appreciate most about Directus is that authentication is built in. Registration, login, email verification, and password reset — all handled without reaching for a third party auth service like Auth0 or Clerk.

Here’s how I implement the full auth flow in a TanStack Start app using the Directus SDK.

User Registration

The SDK’s registerUser function handles registration. You pass the email, password and any additional fields. The verification_url tells Directus where to redirect the user after they click the link in their email — Directus appends the token to that URL automatically.

export async function registerUser(
  email: string,
  password: string,
  firstName: string,
  lastName: string,
) {
  const options = {
    first_name: firstName,
    last_name: lastName,
    verification_url: `${import.meta.env.VITE_TANSTACK_URL}/auth/verify-email`,
  };
  return await directus.request(
    registerUserDirectus(email, password, options),
  );
}

Directus sends the verification email automatically via your configured SMTP provider. I use Resend — SMTP is configured directly in the Docker Compose file via environment variables and the whole setup takes just a few minutes.

EMAIL_TRANSPORT: smtp
EMAIL_SMTP_HOST: smtp.resend.com
EMAIL_SMTP_PORT: 465
EMAIL_SMTP_USER: resend
EMAIL_SMTP_PASSWORD: your_resend_api_key
EMAIL_FROM: [email protected]

Login

Logging in is a single call on the Directus client. Session cookies are handled automatically thanks to the credentials: 'include' config set up on the client.

export async function loginUser(email: string, password: string) {
  return await directus.login({ email, password });
}

Clean, no token management, no localStorage juggling. The session is maintained via cookie.

Email Verification

When the user clicks the link in their verification email, they land on your /auth/verify-email route with a token in the query string. You take that token and hit Directus’s verify endpoint directly.

function VerifyEmailComponent() {
  const { token } = Route.useSearch();
  const [status, setStatus] = useState<
    'verifying' | 'success' | 'error' | 'pending'
  >('pending');

  useEffect(() => {
    if (!token) return;

    async function verify() {
      setStatus('verifying');
      try {
        const response = await fetch(
          `${import.meta.env.VITE_DIRECTUS_URL}/users/register/verify-email?token=${token}`,
          { method: 'GET' },
        );
        if (response.ok) {
          setStatus('success');
        } else {
          setStatus('error');
        }
      } catch (err) {
        setStatus('error');
      }
    }
    verify();
  }, [token]);
}

The status state drives your UI — show a spinner while verifying, a success message on completion, or an error state if the token is invalid or expired.

Password Reset

The password reset flow works the same way — Directus emails the user a reset link with a token, they land on your reset page, and you POST the new password along with the token to Directus’s reset endpoint.

const handleSubmit = async (e: React.FormEvent) => {
  e.preventDefault();
  if (password !== confirm) {
    setError('Passwords do not match.');
    return;
  }
  setLoading(true);
  setError(null);

  try {
    const response = await fetch(
      `${import.meta.env.VITE_DIRECTUS_URL}/auth/password/reset`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ token, password }),
      },
    );

    if (response.ok || response.status === 204) {
      navigate({ to: '/auth/login' });
    } else {
      setError('Failed to reset password. The link may have expired.');
    }
  } catch {
    setError('Something went wrong. Please try again.');
  } finally {
    setLoading(false);
  }
};

A 204 response means success — redirect the user to login. Handle expired tokens gracefully with a clear error message.

What Directus Handles For You

  • ✅ Sending the verification email — via your SMTP provider configured in Docker Compose
  • ✅ Generating and validating tokens
  • ✅ Sending the password reset email
  • ✅ Session management via cookies
  • ✅ Secure password storage

All you need is your SMTP credentials added to your Docker Compose file. I use Resend for email delivery — it’s straightforward to set up and works reliably. Everything else is handled by Directus out of the box.

This is the auth setup I use across all my TanStack Start projects. Combined with Directus roles and permissions, it covers everything a production app needs without adding a separate auth service to your stack.

Have questions about the setup? Drop a comment below.

Help pls

I am actually very confused.

So I got AI to code in a POST request to /api ,so front-end is supposedly done. It tells me to do this:
Create a Vercel Serverless Function
In your repo, add a new file:

/api/x.js
This is where you call OpenAI. Your client will call /api/x.

I have no idea how to do this. Where do I click in Vercel for this…

But I have added the environmental variable of the API key.

So how do I do the serverless function?