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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
**/TestResults/
.git/
docs/
design/
tests/
*.md
*.txt
Expand Down
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* whitespace=trailing-space,space-before-tab,cr-at-eol
*.sh text eol=lf
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ jobs:
- name: Test
run: dotnet test --project tests/MicroStack.Tests/MicroStack.Tests.csproj -c Release --no-build

- name: Test UI components
run: dotnet test --project tests/MicroStack.UI.Tests/MicroStack.UI.Tests.csproj -c Release --no-build

- name: Pack NuGet packages
run: dotnet pack src/MicroStack.Aspire.Hosting/MicroStack.Aspire.Hosting.csproj -c Release --no-build --output ./packages

Expand Down Expand Up @@ -113,5 +116,8 @@ jobs:
npm run typecheck
npm test

- name: Smoke test container
run: sh scripts/smoke-container.sh microstack:ci

- name: Report container image size
run: docker images microstack
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ jobs:
- name: Test
run: dotnet test --project tests/MicroStack.Tests/MicroStack.Tests.csproj -c Release --no-build

- name: Test UI components
run: dotnet test --project tests/MicroStack.UI.Tests/MicroStack.UI.Tests.csproj -c Release --no-build

- name: Pack NuGet packages
run: dotnet pack src/MicroStack.Aspire.Hosting/MicroStack.Aspire.Hosting.csproj -c Release --no-build --output ./packages

Expand Down Expand Up @@ -159,6 +162,9 @@ jobs:
npm run typecheck
npm test

- name: Smoke test container
run: sh scripts/smoke-container.sh ghcr.io/${{ github.repository_owner }}/microstack:${{ inputs.version }}

- name: Push container image to GHCR
run: |
docker push ghcr.io/${{ github.repository_owner }}/microstack:${{ inputs.version }}
Expand Down
19 changes: 12 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@ FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine AS build
RUN apk add --no-cache clang binutils musl-dev build-base zlib-dev zlib-static
WORKDIR /src

# Copy props/solution files first for layer caching
# Copy props/project files first for layer caching
COPY Directory.Build.props ./
COPY MicroStack.slnx ./
COPY src/MicroStack/MicroStack.csproj src/MicroStack/
COPY src/MicroStack.UI.Client/MicroStack.UI.Client.csproj src/MicroStack.UI.Client/
COPY src/MicroStack.Admin.Contracts/MicroStack.Admin.Contracts.csproj src/MicroStack.Admin.Contracts/

RUN dotnet restore src/MicroStack/MicroStack.csproj -r linux-musl-x64

# Copy source and publish
COPY src/MicroStack/ src/MicroStack/
RUN dotnet publish src/MicroStack/MicroStack.csproj -c Release -r linux-musl-x64 -o /app
# Copy source and publish the API with its browser assets
COPY src/ src/
RUN dotnet publish src/MicroStack/MicroStack.csproj -c Release -r linux-musl-x64 -o /out/microstack

FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine
WORKDIR /app
COPY --from=build /out/microstack/ /app/

FROM alpine:3.21
RUN apk add --no-cache libstdc++ libgcc
COPY --from=build /app /app
ENV ASPNETCORE_HTTP_PORTS=4566
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
EXPOSE 4566
ENTRYPOINT ["/app/MicroStack"]
3 changes: 3 additions & 0 deletions MicroStack.slnx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<Solution>
<Folder Name="/src/">
<Project Path="src/MicroStack.Admin.Contracts/MicroStack.Admin.Contracts.csproj" />
<Project Path="src/MicroStack/MicroStack.csproj" />
<Project Path="src/MicroStack.Aspire.Hosting/MicroStack.Aspire.Hosting.csproj" />
<Project Path="src/MicroStack.LambdaBootstrap/MicroStack.LambdaBootstrap.csproj" />
<Project Path="src/MicroStack.UI.Client/MicroStack.UI.Client.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/MicroStack.Tests/MicroStack.Tests.csproj" />
<Project Path="tests/MicroStack.UI.Tests/MicroStack.UI.Tests.csproj" />
<Project Path="tests/MicroStack.Aspire.Tests.AppHost/MicroStack.Aspire.Tests.AppHost.csproj" />
<Project Path="tests/MicroStack.Aspire.Tests/MicroStack.Aspire.Tests.csproj" />
<Project Path="tests/TestLambdaFunctions/SimpleHandler/SimpleHandler.csproj" />
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,31 @@ dotnet run --project src/MicroStack/MicroStack.csproj
curl http://localhost:4566/_microstack/health
```

## Admin UI

MicroStack includes a web UI on the same gateway port:

- **AWS/API endpoint:** `http://localhost:4566`
- **UI endpoint:** `http://localhost:4566/ui/`

An unsigned browser navigation to `http://localhost:4566/` redirects to `/ui/`.
SDK, signed, presigned, and non-HTML root requests retain AWS behavior.

Local builds include the browser client's static assets. Native publishing builds
the client separately. The client keeps its `browser-wasm` runtime identifier
even when restore is invoked with the server's native runtime identifier.

The UI includes:

- **Services** — a searchable directory of all supported services
- **Resource Explorer** — read-only, account-aware inspection of retained
resources, configuration, content, and configured connections
- **Overview** — service health, resource counts, and the global reset control
- **Request Log** — recent AWS API calls (service, action, account, status, duration)

For the separate, synthetic design reference (not the running Admin UI), see the
[Resource Explorer prototype](design/resource-explorer/README.md).

## Usage

Point any AWS SDK client at `http://localhost:4566`:
Expand Down
182 changes: 182 additions & 0 deletions design/resource-explorer/DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
---
name: MicroStack resource inspection prototype
description: A familiar developer console for read-only local resource inspection.
colors:
ink: "#202c3d"
muted: "#526176"
line: "#dbe1e9"
blue: "#165dca"
blue-soft: "#edf4ff"
surface: "#ffffff"
nav: "#f7f9fc"
green: "#267048"
amber: "#795100"
typography:
directory-heading:
fontSize: "2rem"
fontWeight: 650
body:
fontFamily: '"Segoe UI", system-ui, -apple-system, sans-serif'
fontSize: "16px"
lineHeight: 1.5
headline:
fontSize: "1.625rem"
fontWeight: 650
lineHeight: 1.25
letterSpacing: "-.025em"
title:
fontSize: "1.25rem"
fontWeight: 650
letterSpacing: "-.02em"
data:
fontFamily: 'Consolas, "SFMono-Regular", monospace'
fontSize: ".8125rem"
rounded:
control: "4px"
inspector: "7px"
spacing:
small: "8px"
medium: "16px"
panel: "24px"
components:
button-primary:
backgroundColor: "{colors.blue}"
textColor: "{colors.surface}"
rounded: "{rounded.control}"
padding: "7px 12px"
---

# Design System: MicroStack Resource Mockups

## Overview

**Creative North Star: "The local resource workbench"**

A task-oriented console for developers moving from a service to a resource, then
its contents, configuration, and configured connections. The user chose familiar
developer-console conventions rather than an experimental visual direction.
Specific reference products were not endorsed.

This document describes the isolated prototype, not an approved production
redesign. The user selected services home -> dedicated split inspector as the new
prototype direction to avoid an ever-growing services rail. Alternative
compositions and their comparison controls have been removed. The live Blazor
application is unchanged; data legibility and preservation of debugging context
take priority over decoration.

## Colors

Blue identifies navigation, selected rows, links, and active tabs. White inspection
surfaces sit beside cool-gray navigation, with subtle borders defining sections.
Ink and muted text distinguish primary data from supporting metadata. Green and
amber statuses always carry text; color alone never asserts health or delivery.
Official AWS artwork retains its own service-category colors. Those asset colors
identify services, not selection or health; do not recolor or grayscale the icons.

## Typography

System sans-serif avoids font downloads and fits native development tools.
Consolas/SFMono monospace is reserved for identifiers, keys, and payloads.
Service headings are 1.625rem and resource titles 1.25rem on desktop; data,
controls, and supporting labels use .75rem to .9375rem. Narrow headings reduce
to 1.375rem and 1.0625rem. Payload line height is 1.75 for nested JSON.

UI timestamps use UTC ISO 8601 with a full date, seconds, and a `Z` suffix
(for example, `2026-09-11T10:20:00Z`), including object metadata, message lists,
activity logs, and snapshot labels. Durations remain human-readable.

## Layout

The services home is a searchable directory, not a dashboard of status cards.
Grouped lists occupy two columns on desktop and one below 760px, with a maximum
1400px page width. Availability text distinguishes the five clickable mockup
inspectors, unimplemented inspectors, and an explicitly synthetic disabled example.
Search includes service names, identifiers, and categories. A checkbox restricts
the list to services with example inspectors.

The only workspace is a split inspector: a persistent 220px resource index beside
inspection content, without a services rail. All services and a compact switcher
provide cross-service access. The current service in the breadcrumb opens a
searchable dropdown: All services / selected service. Entries sort alphabetically
by displayed name and filter by short or full service name. All 40 catalog entries
appear in the scrollable list. Services without mock inspectors are labeled and
marked aria-disabled; they remain discoverable by keyboard but cannot navigate
to an unfinished inspector. The search uses an
accessible combobox and listbox, with arrow navigation, Enter to select, and Escape
to dismiss and restore focus. Tab moves from the filter to the active result;
the list has one roving tab stop. Arrow keys and Home/End move focus within the
list, Shift+Tab returns to the filter, and Tab from a result leaves the picker.
The focused result has an inset focus outline that is not clipped by list scrolling.
Typing on the closed trigger also starts a search.
No matches are announced explicitly; choosing the current service preserves its
resource selection. There is no separate switcher on the right.
Main padding is 18px 28px.
The breadcrumb and account/configured-region scope share one aligned desktop
header row, with scope on the right. They wrap naturally on narrow screens;
scope remains visible on the services home when the breadcrumb is hidden.
At 1200px and below the inspector stacks records above payloads.
At 1000px resource-index width and panel padding contract. At 760px contents
stack and Browse resources opens a focused index.
Selecting a resource returns to detail. Long identifiers wrap; payloads and wide
activity tables scroll within their own containers, not the page.

Lists expose loaded counts and pagination. The large-list sample generates 125
content entries in pages of 10; it is not a server-side scalability claim.

## Elevation & Depth

Borders and surface tones carry almost all grouping. Toast feedback has a modest
floating shadow; the service dropdown uses a restrained offset shadow to separate
it from the inspector beneath. No decorative
gradients, hero treatments, or animated charts compete with inspected data.
State examples and local refresh feedback do not depend on animation.

## Shapes

Controls and status tags use restrained 4px corners. The inspector uses 7px corners
on desktop and 5px on narrow screens. Data sections remain rectangular and aligned.
The existing MicroStack logo supplies product identity.

## Components

All 40 directory services have locally served, unmodified AWS SVG artwork from
the July 31, 2026 Architecture Icons release. Icons also appear in the searchable
switcher, current-service breadcrumb, inspector headings, and connection rows.
Sizes are 28px in the directory, 24px in results/connections, 20px in the breadcrumb,
and 32px at the service heading. Image elements preserve proportions and use empty
alt text because visible labels already identify each service.

The two API Gateway entries, two Cognito entries, and RDS/RDS Data share family
artwork. S3 Files, CloudWatch Logs, STS, and Application Load Balancer have dedicated
resource icons. `aws-icon-sources.json` records their official archive paths.
Functional glyphs such as search, copy, and arrows remain neutral inline SVGs;
AWS artwork is never substituted for MicroStack branding.

Service buttons use selected background and text; resource buttons also expose
pressed state. Tabs use roving tabindex with arrow, Home, and End navigation.
Controls have a visible 3px focus outline; the page provides a skip link.

Each service has a distinct content model: S3 keys and virtual prefixes with
bounded-preview examples; SQS non-consuming sample message snapshots; DynamoDB
typed items; SNS subscriptions; EventBridge buses, rules, patterns, and targets.
Configuration and service/account activity share consistent secondary tabs.

Connections describe configured relationships, never delivery traces. Following
one retains an explicit return trail, including selected item, tab, prefix,
filter, page, and example state. Missing and external destinations are not
clickable internal resources. Copy controls announce success or explain clipboard
denial; errors and empty/loading/stale states remain explicit.

## Do's and Don'ts

- Keep synthetic data, account, and configured-region scope visible.
- Keep the default services catalog on its home page, not in a growing rail.
- Preserve service -> resource -> contents as the main navigation path.
- Distinguish configuration from observations; never imply causal delivery.
- Label proposed non-consuming SQS snapshots as requiring a dedicated admin API.
- Keep binary and oversized objects metadata-only when a preview is unavailable.
- Do not equate a loaded-subset filter with a query or complete scan.
- Do not add provisioning controls, live API calls, or inferred relationships.
- Do not treat prototype navigation approval as permission to change production.

Open product and API decisions are recorded in `notes.html` and `PRODUCT.md`.
85 changes: 85 additions & 0 deletions design/resource-explorer/PRODUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Product

<!-- impeccable:product-schema 1 -->

## Platform

web

## Users

Developers inspecting and debugging a local MicroStack instance. Their primary
path is service -> resource -> contents, with connected resources and relevant
activity available in context.

## Product Purpose

MicroStack emulates AWS services locally. This prototype explores how developers
can inspect resources and contents without switching repeatedly to SDK or CLI
commands. It is a design artifact, not an extension of the running emulator.

## Operating Context

The existing admin application is Blazor WebAssembly on a separate UI port.
The emulator is a Native AOT .NET application. Resources may belong to different
accounts, while the configured region must not be mistaken for per-region
isolation. The prototype uses only clearly labeled synthetic data.
The UI assumes one local instance, so it needs no local-instance indicator or
instance switcher.

## Capabilities and Constraints

- Representative inspectors: S3, SQS, DynamoDB, SNS, and EventBridge.
- Inspect and debug, not provision or mutate resources.
- SNS subscriptions and EventBridge rules/targets provide configured connections;
they do not establish that an event matched or was delivered.
- Existing admin resource summaries cover SQS, S3, and DynamoDB only.
- Current request logs record service, action, account, timestamp, status, and
duration, not reliable resource IDs or causal trace IDs.
- Non-consuming SQS inspection is a proposed admin capability, not ReceiveMessage.
- Backend APIs, live integration, destructive actions, and production changes are
excluded from this prototype.
- Navigation should accommodate other services without invented inspectors.
- Confirmed navigation decision (11 September 2026): service-first home and a
split inspector per service. This is the selected direction, not merely a
comparison default. The searchable, grouped services home opens a resource
list beside an inspector, without a permanent services rail.
- All services navigation and a compact service switcher remain available inside
inspection. Alternative layouts and comparison controls have been removed.
This design decision does not itself authorize production implementation.
- The current-service breadcrumb opens a searchable, alphabetically sorted
switcher with arrow-key navigation, Enter selection, and Escape dismissal.

## Brand Commitments

MicroStack name and factual terminology remain. The user explicitly approved
replacing the Bootstrap template appearance with a purpose-designed developer
tool. The user subsequently selected the familiar developer console direction.
No specific reference products were supplied: conventional cloud-console
navigation and database-inspector patterns are working assumptions, not endorsed
references. Use a restrained light interface for reading data alongside other
development windows; this is a prototype decision, not a product requirement.

Use official AWS service/resource icons to identify all 40 catalog entries,
with corresponding family icons for related APIs. Keep AWS artwork unmodified
and local, alongside explicit text labels. Retain the MicroStack logo as the
product identity; AWS icons do not imply AWS endorsement.

## Evidence on Hand

The repository has a working initial dashboard, request log, and generic resource
lists, plus a MicroStack logo. Service handlers provide related AWS operations.
Synthetic order-processing examples are illustrations, never evidence of live
resources or observed deliveries.

## Product Principles

- Preserve context while moving from a resource to its contents or connections.
- Separate configured state, observed requests, and inferred relationships.
- Expose partial, stale, missing, and unsupported data rather than hiding limits.
- Optimize for task clarity and scanning rather than a marketing presentation.

## Accessibility & Inclusion

The prototype plan includes keyboard-accessible controls, visible focus, text
status labels, readable payloads, and a focused detail view on narrow screens.
Loading
Loading