mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
fix merge request
This commit is contained in:
commit
f98a740ee7
18 changed files with 43335 additions and 61 deletions
|
|
@ -3,64 +3,53 @@ FROM library/python:3.12-bookworm
|
|||
ARG USER=vscode
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=1000
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install system dependencies in a single layer
|
||||
# Base CLI tooling (sudo, git, ripgrep/fd for editors, etc.).
|
||||
RUN apt update && apt install -y --no-install-recommends \
|
||||
<<<<<<< HEAD
|
||||
sudo jq vim curl bash-completion iputils-ping \
|
||||
&& apt autoremove -y \
|
||||
=======
|
||||
sudo jq vim curl bash-completion \
|
||||
ripgrep fd-find git make unzip \
|
||||
>>>>>>> main
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create the user and grant sudo privileges
|
||||
RUN useradd -m -s /bin/bash ${USER} \
|
||||
# Passwordless-sudo dev user (UID/GID injected from the host via compose).
|
||||
RUN useradd -m -s /bin/bash -u ${USER_UID} ${USER} \
|
||||
&& echo "${USER} ALL=(ALL) NOPASSWD: ALL" >/etc/sudoers.d/${USER} \
|
||||
&& chmod 0440 /etc/sudoers.d/${USER}
|
||||
|
||||
# Install Node.js 22 (from NodeSource)
|
||||
# Node 22 (NodeSource).
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt install -y nodejs \
|
||||
&& node -v \
|
||||
&& npm -v
|
||||
&& apt install -y nodejs
|
||||
|
||||
# # Install aws
|
||||
# RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||
# RUN unzip awscliv2.zip
|
||||
# RUN ./aws/install
|
||||
|
||||
# # Install terraform
|
||||
# RUN apt-get update && sudo apt-get install -y gnupg software-properties-common
|
||||
# RUN wget -O- https://apt.releases.hashicorp.com/gpg | \
|
||||
# gpg --dearmor | \
|
||||
# sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
|
||||
# RUN echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
|
||||
# https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
|
||||
# tee /etc/apt/sources.list.d/hashicorp.list
|
||||
# RUN apt update
|
||||
# RUN apt-get install terraform
|
||||
# RUN terraform -install-autocomplete
|
||||
|
||||
# Install Neovim (latest) + LazyVim deps
|
||||
RUN curl -fsSL https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz \
|
||||
| tar -xz -C /opt \
|
||||
&& ln -s /opt/nvim-linux-x86_64/bin/nvim /usr/local/bin/nvim \
|
||||
&& apt update && apt install -y --no-install-recommends \
|
||||
ripgrep fd-find git make unzip \
|
||||
# GitHub CLI — used by the postCreate skill installer to authenticate against
|
||||
# private Hestia-Homes repos via the host's mounted ~/.config/gh.
|
||||
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
|
||||
| dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
|
||||
> /etc/apt/sources.list.d/github-cli.list \
|
||||
&& apt update && apt install -y gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Claude
|
||||
# Download Neovim (latest release tarball from GitHub) and symlink onto PATH.
|
||||
RUN curl -fsSL https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz \
|
||||
| tar -xz -C /opt \
|
||||
&& ln -s /opt/nvim-linux-x86_64/bin/nvim /usr/local/bin/nvim
|
||||
|
||||
USER ${USER}
|
||||
# Bootstrap LazyVim starter config
|
||||
|
||||
# LazyVim starter config (.git stripped so the user owns the files).
|
||||
RUN git clone https://github.com/LazyVim/starter /home/${USER}/.config/nvim \
|
||||
&& rm -rf /home/${USER}/.config/nvim/.git
|
||||
# Install Claude + plugins + skills
|
||||
RUN curl -fsSL https://claude.ai/install.sh | bash \
|
||||
&& export PATH="/home/${USER}/.local/bin:${PATH}" \
|
||||
&& claude plugin marketplace add JuliusBrussee/caveman \
|
||||
&& claude plugin install caveman@caveman
|
||||
ENV PATH="/home/vscode/.local/bin:${PATH}"
|
||||
|
||||
# Download + install Claude Code CLI (installs to ~/.local/bin).
|
||||
RUN curl -fsSL https://claude.ai/install.sh | bash
|
||||
ENV PATH="/home/${USER}/.local/bin:${PATH}"
|
||||
|
||||
USER root
|
||||
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /workspaces/assessment-model
|
||||
WORKDIR /workspaces/assessment-model
|
||||
|
|
|
|||
|
|
@ -4,14 +4,24 @@
|
|||
"service": "frontend",
|
||||
"remoteUser": "vscode",
|
||||
"workspaceFolder": "/workspaces/assessment-model",
|
||||
"initializeCommand": "docker network create shared-dev 2>/dev/null || true",
|
||||
"postStartCommand": "bash .devcontainer/post-install.sh",
|
||||
"forwardPorts": [3000], # 3000 = Next.js
|
||||
"appPort": ["3000:3000"], # For devcontainer shell
|
||||
|
||||
// Host preflight: ensure GitHub auth exists before we try to build.
|
||||
// Either ~/.config/gh (from `gh auth login`) or a GITHUB_TOKEN env var.
|
||||
"initializeCommand": "test -d \"$HOME/.config/gh\" || test -n \"$GITHUB_TOKEN\" || { echo >&2 'error: no GitHub auth found. Run `gh auth login && gh auth setup-git` on the host, or export GITHUB_TOKEN, then retry.'; exit 1; }",
|
||||
|
||||
// Install Domna's curated skill set (pinned to 0.0.5) into this workspace,
|
||||
// then install npm deps. `gh repo clone` handles private-repo auth using
|
||||
// the mounted host ~/.config/gh.
|
||||
"postCreateCommand": "gh repo clone Hestia-Homes/agentic-toolkit /tmp/agentic-toolkit -- --branch 0.0.5 --depth 1 && bash /tmp/agentic-toolkit/setup.sh && npm install",
|
||||
|
||||
"forwardPorts": [3000],
|
||||
"appPort": ["3000:3000"],
|
||||
|
||||
"mounts": [
|
||||
// Optional, just makes getting from Downloads (local env) easier
|
||||
"source=${localEnv:HOME},target=/workspaces/home,type=bind"
|
||||
],
|
||||
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ services:
|
|||
build:
|
||||
context: ..
|
||||
dockerfile: .devcontainer/Dockerfile
|
||||
# Match host UID/GID so files written in the container aren't root-owned.
|
||||
args:
|
||||
USER_UID: ${UID:-1000}
|
||||
USER_GID: ${GID:-1000}
|
||||
|
|
@ -13,8 +14,14 @@ services:
|
|||
volumes:
|
||||
- ..:/workspaces/assessment-model
|
||||
- ~/.gitconfig:/home/vscode/.gitconfig:ro
|
||||
# GitHub CLI auth from host (created by `gh auth login`). Used by the
|
||||
# postCreate skill installer to clone private Hestia-Homes repos.
|
||||
- ~/.config/gh:/home/vscode/.config/gh:ro
|
||||
environment:
|
||||
# Host SSH agent — for `git push` etc. inside the container.
|
||||
- SSH_AUTH_SOCK=${SSH_AUTH_SOCK:-}
|
||||
# Fallback HTTPS auth if ~/.config/gh isn't present on the host.
|
||||
- GITHUB_TOKEN=${GITHUB_TOKEN:-}
|
||||
networks:
|
||||
- frontend-net
|
||||
- shared-dev
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
npm install;
|
||||
|
|
@ -23,8 +23,6 @@ CONFIG_PATH="${REPO_ROOT}/.devcontainer/devcontainer.json"
|
|||
|
||||
VALID_COMMANDS=(up shell down rebuild)
|
||||
|
||||
# --- helpers ---------------------------------------------------------------
|
||||
|
||||
usage() {
|
||||
sed -n '3,15p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
|
||||
exit "${1:-0}"
|
||||
|
|
@ -36,8 +34,7 @@ die() {
|
|||
}
|
||||
|
||||
in_list() {
|
||||
local needle="$1"
|
||||
shift
|
||||
local needle="$1"; shift
|
||||
local item
|
||||
for item in "$@"; do
|
||||
[[ "${item}" == "${needle}" ]] && return 0
|
||||
|
|
@ -52,10 +49,7 @@ container_id() {
|
|||
--filter "label=devcontainer.config_file=${CONFIG_PATH}"
|
||||
}
|
||||
|
||||
# --- argument parsing ------------------------------------------------------
|
||||
|
||||
[[ $# -eq 1 ]] || usage 1
|
||||
|
||||
COMMAND="$1"
|
||||
|
||||
in_list "${COMMAND}" "${VALID_COMMANDS[@]}" \
|
||||
|
|
@ -65,8 +59,6 @@ in_list "${COMMAND}" "${VALID_COMMANDS[@]}" \
|
|||
|
||||
DC_ARGS=(--workspace-folder "${REPO_ROOT}")
|
||||
|
||||
# --- dispatch --------------------------------------------------------------
|
||||
|
||||
case "${COMMAND}" in
|
||||
up)
|
||||
echo ">> bringing up devcontainer"
|
||||
|
|
@ -74,8 +66,6 @@ case "${COMMAND}" in
|
|||
;;
|
||||
|
||||
shell)
|
||||
# Auto-up if not already running. `devcontainer up` is idempotent —
|
||||
# it reuses an existing container, so this is cheap on warm starts.
|
||||
if [[ -z "$(container_id)" ]]; then
|
||||
echo ">> devcontainer not running, bringing it up first"
|
||||
devcontainer up "${DC_ARGS[@]}"
|
||||
|
|
|
|||
2
src/app/db/migrations/0187_mean_salo.sql
Normal file
2
src/app/db/migrations/0187_mean_salo.sql
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE "epc_window" RENAME COLUMN "pvc_frame" TO "frame_material";--> statement-breakpoint
|
||||
ALTER TABLE "epc_window" ALTER COLUMN "transmission_data_source" SET DATA TYPE text;
|
||||
1
src/app/db/migrations/0188_wild_morph.sql
Normal file
1
src/app/db/migrations/0188_wild_morph.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE "epc_window" ALTER COLUMN "frame_material" DROP NOT NULL;
|
||||
2
src/app/db/migrations/0189_high_leech.sql
Normal file
2
src/app/db/migrations/0189_high_leech.sql
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE "epc_property" ADD COLUMN "uploaded_file_id" bigint;--> statement-breakpoint
|
||||
ALTER TABLE "epc_property" ADD CONSTRAINT "epc_property_uploaded_file_id_uploaded_files_id_fk" FOREIGN KEY ("uploaded_file_id") REFERENCES "public"."uploaded_files"("id") ON DELETE no action ON UPDATE no action;
|
||||
1
src/app/db/migrations/0190_worried_drax.sql
Normal file
1
src/app/db/migrations/0190_worried_drax.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE "epc_property" ADD CONSTRAINT "epc_property_uploaded_file_id_unique" UNIQUE("uploaded_file_id");
|
||||
10
src/app/db/migrations/0191_soft_ezekiel_stane.sql
Normal file
10
src/app/db/migrations/0191_soft_ezekiel_stane.sql
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "survey_type" text;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "measures_for_pibi_ordered" text;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "pibi_order_date" timestamp (6) with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "pibi_completed_date" timestamp (6) with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "property_halted_date" timestamp (6) with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "property_halted_reason" text;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "technical_approved_measures_for_install" text;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "sent_to_installer_for_pricing" timestamp (6) with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "domna_survey_required" boolean;--> statement-breakpoint
|
||||
ALTER TABLE "hubspot_deal_data" ADD COLUMN "domna_survey_date" timestamp (6) with time zone;
|
||||
8616
src/app/db/migrations/meta/0187_snapshot.json
Normal file
8616
src/app/db/migrations/meta/0187_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
8616
src/app/db/migrations/meta/0188_snapshot.json
Normal file
8616
src/app/db/migrations/meta/0188_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
8635
src/app/db/migrations/meta/0189_snapshot.json
Normal file
8635
src/app/db/migrations/meta/0189_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
8643
src/app/db/migrations/meta/0190_snapshot.json
Normal file
8643
src/app/db/migrations/meta/0190_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
8703
src/app/db/migrations/meta/0191_snapshot.json
Normal file
8703
src/app/db/migrations/meta/0191_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1310,6 +1310,41 @@
|
|||
"when": 1777028605680,
|
||||
"tag": "0186_equal_baron_zemo",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 187,
|
||||
"version": "7",
|
||||
"when": 1777307158192,
|
||||
"tag": "0187_mean_salo",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 188,
|
||||
"version": "7",
|
||||
"when": 1777364161220,
|
||||
"tag": "0188_wild_morph",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 189,
|
||||
"version": "7",
|
||||
"when": 1777392468614,
|
||||
"tag": "0189_high_leech",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 190,
|
||||
"version": "7",
|
||||
"when": 1777392681924,
|
||||
"tag": "0190_worried_drax",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 191,
|
||||
"version": "7",
|
||||
"when": 1777560763716,
|
||||
"tag": "0191_soft_ezekiel_stane",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { pgTable, uuid, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import { pgTable, uuid, text, timestamp, boolean } from "drizzle-orm/pg-core";
|
||||
import { InferModel } from "drizzle-orm";
|
||||
|
||||
export const hubspotDealData = pgTable("hubspot_deal_data", {
|
||||
|
|
@ -58,6 +58,17 @@ export const hubspotDealData = pgTable("hubspot_deal_data", {
|
|||
confirmedSurveyTime: text("confirmed_survey_time"),
|
||||
surveyedDate: timestamp("surveyed_date", { precision: 6, withTimezone: true }),
|
||||
|
||||
surveyType: text("survey_type"),
|
||||
measuresForPibiOrdered: text("measures_for_pibi_ordered"),
|
||||
pibiOrderDate: timestamp("pibi_order_date", { precision: 6, withTimezone: true }),
|
||||
pibiCompletedDate: timestamp("pibi_completed_date", { precision: 6, withTimezone: true }),
|
||||
propertyHaltedDate: timestamp("property_halted_date", { precision: 6, withTimezone: true }),
|
||||
propertyHaltedReason: text("property_halted_reason"),
|
||||
technicalApprovedMeasuresForInstall: text("technical_approved_measures_for_install"),
|
||||
sentToInstallerForPricing: timestamp("sent_to_installer_for_pricing", { precision: 6, withTimezone: true }),
|
||||
domnaSurveyRequired: boolean("domna_survey_required"),
|
||||
domnaSurveyDate: timestamp("domna_survey_date", { precision: 6, withTimezone: true }),
|
||||
|
||||
createdAt: timestamp("created_at", { precision: 6, withTimezone: true })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import { portfolio, PortfolioStatus } from "./portfolio";
|
|||
import { InferModel } from "drizzle-orm";
|
||||
import { materialTypeEnum } from "./materials";
|
||||
import { sql } from "drizzle-orm";
|
||||
import { uploadedFiles } from "./uploaded_files";
|
||||
|
||||
// This is a placeholder for the property schema
|
||||
export interface PropertyMeta {
|
||||
|
|
@ -422,6 +423,9 @@ export const epcProperty = pgTable(
|
|||
portfolioId: bigint("portfolio_id", { mode: "bigint" })
|
||||
// .notNull()
|
||||
.references(() => portfolio.id),
|
||||
uploadedFileId: bigint("uploaded_file_id", { mode: "bigint" })
|
||||
.unique()
|
||||
.references(() => uploadedFiles.id),
|
||||
|
||||
// Identity / admin
|
||||
uprn: bigint("uprn", { mode: "bigint" }),
|
||||
|
|
@ -733,7 +737,6 @@ export const epcWindow = pgTable(
|
|||
.notNull()
|
||||
.references(() => epcProperty.id),
|
||||
|
||||
pvcFrame: text("pvc_frame").notNull(),
|
||||
glazingGap: text("glazing_gap").notNull(),
|
||||
orientation: text("orientation").notNull(),
|
||||
windowType: text("window_type").notNull(),
|
||||
|
|
@ -744,12 +747,13 @@ export const epcWindow = pgTable(
|
|||
windowLocation: text("window_location").notNull(),
|
||||
windowWallType: text("window_wall_type").notNull(),
|
||||
permanentShuttersPresent: boolean("permanent_shutters_present").notNull(),
|
||||
frameMaterial: text("frame_material"),
|
||||
frameFactor: real("frame_factor"),
|
||||
permanentShuttersInsulated: text("permanent_shutters_insulated"),
|
||||
|
||||
// Transmission details (inlined)
|
||||
transmissionUValue: real("transmission_u_value"),
|
||||
transmissionDataSource: integer("transmission_data_source"),
|
||||
transmissionDataSource: text("transmission_data_source"),
|
||||
transmissionSolarTransmittance: real("transmission_solar_transmittance"),
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue