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
159 changes: 159 additions & 0 deletions .github/workflows/ai-pr-summary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: PR AI Summary

on:
pull_request:
types: [opened, synchronize, reopened]

permissions:
contents: read
pull-requests: write

jobs:
summarize:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Get PR diff
id: diff
run: |
BASE="${{ github.event.pull_request.base.sha }}"
HEAD="${{ github.event.pull_request.head.sha }}"
# Trae exactamente esos commits (evita problemas de merge-base y shallow clones)
git fetch --no-tags --prune --depth=1 origin $BASE $HEAD
git diff $BASE $HEAD > pr.diff
echo "path=pr.diff" >> $GITHUB_OUTPUT

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install deps
run: |
python -m pip install --upgrade pip
pip install openai==1.* # SDK oficial

- name: Generate AI summary (OpenAI)
id: ai
continue-on-error: true
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
MODEL: gpt-4o-mini
run: |
python - << 'PY'
import os
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

with open("pr.diff","r",encoding="utf-8") as f:
diff = f.read()[:200000] # tope por costos/ruido

prompt = (
"You are a code reviewer. Summarize this PR in 2-20 bullets. "
"Include WHAT changed, WHY it matters, RISKS, TESTS to add, and any BREAKING CHANGES. "
"Highlight key features or changes. Consider markdown as the default output format."
"Keep in mind the following points:"
"1) If DIFF shows only documentation files (e.g., .md/.mdx/.txt/README), state 'Docs-only change', "
" make clear that the change is included only in documentation files, if that is the case, "
" otherwise explain normally, considering the DIFF changes like normal. "
"2) Include a short list of changed file paths as extracted from DIFF. "
"Keep it concise and actionable.\n\nDIFF:\n" + diff
)

resp = client.chat.completions.create(
model=os.getenv("MODEL","gpt-4o-mini"),
temperature=0.2,
messages=[{"role":"user","content":prompt}],
)
text = resp.choices[0].message.content.strip()
with open("summary.txt","w",encoding="utf-8") as f:
f.write(text)
PY

- name: Heuristic fallback if AI failed
if: ${{ steps.ai.outcome == 'failure' }}
run: |
python - << 'PY'
import re, pathlib
diff = pathlib.Path("pr.diff").read_text(encoding="utf-8")

added = len(re.findall(r"^\\+[^+].*$", diff, flags=re.M))
removed = len(re.findall(r"^\\-[^-].*$", diff, flags=re.M))
files = re.findall(r"^\\+\\+\\+ b/(.+)$", diff, flags=re.M)

lower_paths = [f.lower() for f in files]
DOC_EXT = (".md", ".mdx", ".txt", ".rst", ".adoc")
is_doc = lambda p: p.endswith(DOC_EXT) or "/docs/" in p or "/doc/" in p
docs_only = len(files) > 0 and all(is_doc(p) for p in lower_paths)

# ---------- Doc-only summary ----------
if docs_only:
bullets_changed = []
for f in files[:20]: # evita listas enormes
bullets_changed.append(f"- `{f}`")
doc_summary = [
"## PR Summary",
"",
"### WHAT Changed",
"- **Docs-only change** detected from DIFF.",
f"- Files changed ({len(files)}):",
*bullets_changed,
"",
"### WHY It Matters",
"- Improves documentation/README clarity and onboarding experience.",
"",
"### RISKS",
"- None to runtime behavior (documentation only).",
"",
"### TESTS to Add",
"- N/A (no code changes).",
"",
"### BREAKING CHANGES",
"- None.",
]
pathlib.Path("summary.txt").write_text("\n".join(doc_summary), encoding="utf-8")
raise SystemExit(0)

scopes = set()
for f in files:
fl = f.lower()
if "/controller" in fl: scopes.add("controller")
elif "/service" in fl: scopes.add("service")
elif "/repository" in fl or "jparepository" in diff.lower(): scopes.add("repository")
elif "/entity" in fl or "/model" in fl: scopes.add("entity")
elif "application" in fl and (fl.endswith(".yml") or fl.endswith(".yaml") or fl.endswith(".properties")):
scopes.add("config")
elif fl.endswith("test.java"): scopes.add("test")

scope = ",".join(sorted(scopes)) if scopes else "core"
kind = "refactor"
if added and not removed: kind = "feat"
if removed and not added: kind = "chore"
if re.search(r"@Test", diff): kind = "test"
if re.search(r"fix|bug|exception|stacktrace", diff, re.I): kind = "fix"

subject = f"[Fallback] {kind}({scope}): {len(files)} file(s), +{added}/-{removed}"

bullets = []
bullets.append(f"- Files changed: {len(files)}")
bullets.append(f"- Lines: +{added} / -{removed}")
if scopes:
bullets.append(f"- Layers: {', '.join(sorted(scopes))}")
if re.search(r"@Transactional", diff): bullets.append("- Touches transactional boundaries")
if re.search(r"@RestController|@Controller", diff): bullets.append("- Controller changes present")
if re.search(r"@Service", diff): bullets.append("- Service-layer changes present")
if re.search(r"@Repository|JpaRepository", diff): bullets.append("- Repository-layer changes present")
if re.search(r"todo|fixme", diff, re.I): bullets.append("- Contains TODO/FIXME markers")

text = subject + "\\n\\n" + "\\n".join(bullets)
pathlib.Path("summary.txt").write_text(text, encoding="utf-8")
PY

- name: Comment on PR
uses: marocchino/sticky-pull-request-comment@v2
with:
header: ai-pr-summary
recreate: true
path: summary.txt
32 changes: 11 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
The system allows creating, updating, filtering, and sorting products,
as well as tracking key metrics like total stock, inventory value, and average price.

The project was built with a focus on usability, clear data visualization,
responsiveness and its supposed to be bug free. It supports pagination,
search filters, product availability toggling, and sorting by multiple columns.
The project was built with a focus of usability, clear data visualization and
responsiveness, for an easy convenience store inventory management (and It's supposed to be bug free).
It supports pagination, search filters, product availability toggling, and sorting by multiple columns.

## Tech Stack

Expand All @@ -16,21 +16,7 @@ search filters, product availability toggling, and sorting by multiple columns.
- **Backend:** REST API with CRUD and stock control endpoints
[InventoryManagerBS](https://github.com/technologic-technologic/InventoryManagerBS.git)

## Features

- **Product CRUD**

- **Filtering & Searching**

- **Sorting**

- **Stock Management**

- **Inventory Metrics**

- **Pagination**

## Backend API (Expected)
## Backend API (Expected communications)

Business service git URL: https://github.com/technologic-technologic/InventoryManagerBS.git

Expand All @@ -49,16 +35,20 @@ The frontend expects the following API endpoints:

To run the frontend locally:

```bash
# go to directory from repo location
cd inventory-manager
```
```bash
# Install dependencies
npm install
```
```bash
# Run the app on port 8080
npm start
npm run dev
```

```bash
# Run all tests
npm test
# Run tests manually
npm run test
```
Binary file removed documentation/documentation.docx
Binary file not shown.
43 changes: 23 additions & 20 deletions inventory-manager/.gitignore
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local
package-lock.json

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.idea/
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
119 changes: 73 additions & 46 deletions inventory-manager/README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,73 @@
# Getting Started with Create React App

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

## Available Scripts

In the project directory, you can run:

### `npm start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.\
You will also see any lint errors in the console.

### `npm test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `npm run build`

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

### `npm run eject`

**Note: this is a one-way operation. Once you `eject`, you can’t go back!**

If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...

// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
Loading