Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
Son Of Anton
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Son Of Anton
Commits
dbe0dcba
Commit
dbe0dcba
authored
Mar 29, 2026
by
Mahmoud Aglan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gitlab try 1
parent
10eb3289
Changes
9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
2072 additions
and
427 deletions
+2072
-427
FULL_CODEBASE.txt
FULL_CODEBASE.txt
+165
-147
main.py
backend/main.py
+17
-9
models.py
backend/models.py
+46
-0
gitlab_routes.py
backend/routes/gitlab_routes.py
+611
-0
gitlab_service.py
backend/services/gitlab_service.py
+494
-0
App.jsx
frontend/src/App.jsx
+5
-12
api.js
frontend/src/api.js
+88
-115
Sidebar.jsx
frontend/src/components/Sidebar.jsx
+106
-144
GitLabPage.jsx
frontend/src/pages/GitLabPage.jsx
+540
-0
No files found.
FULL_CODEBASE.txt
View file @
dbe0dcba
This diff is collapsed.
Click to expand it.
backend/main.py
View file @
dbe0dcba
...
@@ -20,9 +20,11 @@ from backend.routes.admin_routes import router as admin_router
...
@@ -20,9 +20,11 @@ from backend.routes.admin_routes import router as admin_router
from
backend.routes.knowledge_routes
import
router
as
knowledge_router
from
backend.routes.knowledge_routes
import
router
as
knowledge_router
from
backend.routes.files_routes
import
router
as
files_router
from
backend.routes.files_routes
import
router
as
files_router
from
backend.routes.attachment_routes
import
router
as
attachment_router
from
backend.routes.attachment_routes
import
router
as
attachment_router
from
backend.routes.gitlab_routes
import
router
as
gitlab_router
from
backend.services.bedrock_service
import
close_http_client
from
backend.services.bedrock_service
import
close_http_client
from
backend.services.gitlab_service
import
close_gitlab_client
APP_VERSION
=
"
2.1
.0"
APP_VERSION
=
"
3.0
.0"
APP_BUILD_TIME
=
str
(
int
(
time
.
time
()))
APP_BUILD_TIME
=
str
(
int
(
time
.
time
()))
...
@@ -49,6 +51,18 @@ def _run_migrations():
...
@@ -49,6 +51,18 @@ def _run_migrations():
ChatAttachment
.
__table__
.
create
(
bind
=
engine
,
checkfirst
=
True
)
ChatAttachment
.
__table__
.
create
(
bind
=
engine
,
checkfirst
=
True
)
print
(
" Created chat_attachments table"
)
print
(
" Created chat_attachments table"
)
# GitLab tables
for
table_name
in
(
"gitlab_configs"
,
"gitlab_operations"
,
"gitlab_audit_log"
):
if
table_name
not
in
existing_tables
:
from
backend.models
import
GitLabConfig
,
GitLabOperation
,
GitLabAuditLog
table_map
=
{
"gitlab_configs"
:
GitLabConfig
,
"gitlab_operations"
:
GitLabOperation
,
"gitlab_audit_log"
:
GitLabAuditLog
,
}
table_map
[
table_name
]
.
__table__
.
create
(
bind
=
engine
,
checkfirst
=
True
)
print
(
f
" Created {table_name} table"
)
except
Exception
as
e
:
except
Exception
as
e
:
print
(
f
" Migration note: {e}"
)
print
(
f
" Migration note: {e}"
)
...
@@ -61,6 +75,7 @@ async def lifespan(app: FastAPI):
...
@@ -61,6 +75,7 @@ async def lifespan(app: FastAPI):
print
(
f
"Son of Anton v{APP_VERSION} (build {APP_BUILD_TIME}) is online."
)
print
(
f
"Son of Anton v{APP_VERSION} (build {APP_BUILD_TIME}) is online."
)
yield
yield
await
close_http_client
()
await
close_http_client
()
await
close_gitlab_client
()
print
(
"Son of Anton shutting down."
)
print
(
"Son of Anton shutting down."
)
...
@@ -84,28 +99,21 @@ app.add_middleware(
...
@@ -84,28 +99,21 @@ app.add_middleware(
async
def
add_cache_headers
(
request
:
Request
,
call_next
):
async
def
add_cache_headers
(
request
:
Request
,
call_next
):
response
:
Response
=
await
call_next
(
request
)
response
:
Response
=
await
call_next
(
request
)
path
=
request
.
url
.
path
path
=
request
.
url
.
path
# API responses: never cache
if
path
.
startswith
(
"/api"
):
if
path
.
startswith
(
"/api"
):
response
.
headers
[
"Cache-Control"
]
=
"no-store, no-cache, must-revalidate, max-age=0"
response
.
headers
[
"Cache-Control"
]
=
"no-store, no-cache, must-revalidate, max-age=0"
response
.
headers
[
"Pragma"
]
=
"no-cache"
response
.
headers
[
"Pragma"
]
=
"no-cache"
response
.
headers
[
"Expires"
]
=
"0"
response
.
headers
[
"Expires"
]
=
"0"
# Hashed assets (contain hash in filename): cache aggressively
elif
path
.
startswith
(
"/assets/"
)
and
any
(
c
in
path
for
c
in
[
".js"
,
".css"
]):
elif
path
.
startswith
(
"/assets/"
)
and
any
(
c
in
path
for
c
in
[
".js"
,
".css"
]):
response
.
headers
[
"Cache-Control"
]
=
"public, max-age=31536000, immutable"
response
.
headers
[
"Cache-Control"
]
=
"public, max-age=31536000, immutable"
# HTML and everything else: never cache
elif
path
.
endswith
(
".html"
)
or
not
path
.
startswith
(
"/assets"
):
elif
path
.
endswith
(
".html"
)
or
not
path
.
startswith
(
"/assets"
):
response
.
headers
[
"Cache-Control"
]
=
"no-store, no-cache, must-revalidate, max-age=0"
response
.
headers
[
"Cache-Control"
]
=
"no-store, no-cache, must-revalidate, max-age=0"
response
.
headers
[
"Pragma"
]
=
"no-cache"
response
.
headers
[
"Pragma"
]
=
"no-cache"
response
.
headers
[
"Expires"
]
=
"0"
response
.
headers
[
"Expires"
]
=
"0"
# Always add version header for debugging
response
.
headers
[
"X-App-Version"
]
=
APP_VERSION
response
.
headers
[
"X-App-Version"
]
=
APP_VERSION
response
.
headers
[
"X-Build-Time"
]
=
APP_BUILD_TIME
response
.
headers
[
"X-Build-Time"
]
=
APP_BUILD_TIME
return
response
return
response
# Version endpoint for frontend to check
@
app
.
get
(
"/api/version"
)
@
app
.
get
(
"/api/version"
)
def
get_version
():
def
get_version
():
return
{
"version"
:
APP_VERSION
,
"build"
:
APP_BUILD_TIME
}
return
{
"version"
:
APP_VERSION
,
"build"
:
APP_BUILD_TIME
}
...
@@ -117,6 +125,7 @@ app.include_router(admin_router, prefix="/api/admin", tags=["Admin"])
...
@@ -117,6 +125,7 @@ app.include_router(admin_router, prefix="/api/admin", tags=["Admin"])
app
.
include_router
(
knowledge_router
,
prefix
=
"/api/knowledge"
,
tags
=
[
"Knowledge"
])
app
.
include_router
(
knowledge_router
,
prefix
=
"/api/knowledge"
,
tags
=
[
"Knowledge"
])
app
.
include_router
(
files_router
,
prefix
=
"/api/files"
,
tags
=
[
"Files"
])
app
.
include_router
(
files_router
,
prefix
=
"/api/files"
,
tags
=
[
"Files"
])
app
.
include_router
(
attachment_router
,
prefix
=
"/api"
,
tags
=
[
"Attachments"
])
app
.
include_router
(
attachment_router
,
prefix
=
"/api"
,
tags
=
[
"Attachments"
])
app
.
include_router
(
gitlab_router
,
prefix
=
"/api/gitlab"
,
tags
=
[
"GitLab"
])
FRONTEND_DIR
=
Path
(
__file__
)
.
parent
.
parent
/
"frontend"
/
"dist"
FRONTEND_DIR
=
Path
(
__file__
)
.
parent
.
parent
/
"frontend"
/
"dist"
...
@@ -135,7 +144,6 @@ async def serve_frontend(full_path: str):
...
@@ -135,7 +144,6 @@ async def serve_frontend(full_path: str):
file_path
=
FRONTEND_DIR
/
full_path
file_path
=
FRONTEND_DIR
/
full_path
if
full_path
and
file_path
.
is_file
():
if
full_path
and
file_path
.
is_file
():
resp
=
FileResponse
(
str
(
file_path
))
resp
=
FileResponse
(
str
(
file_path
))
# Don't cache non-hashed static files
resp
.
headers
[
"Cache-Control"
]
=
"no-store, no-cache, must-revalidate, max-age=0"
resp
.
headers
[
"Cache-Control"
]
=
"no-store, no-cache, must-revalidate, max-age=0"
return
resp
return
resp
index
=
FRONTEND_DIR
/
"index.html"
index
=
FRONTEND_DIR
/
"index.html"
...
...
backend/models.py
View file @
dbe0dcba
...
@@ -124,3 +124,49 @@ class KnowledgeDocument(Base):
...
@@ -124,3 +124,49 @@ class KnowledgeDocument(Base):
file_size
=
Column
(
Integer
,
default
=
0
)
file_size
=
Column
(
Integer
,
default
=
0
)
chunk_count
=
Column
(
Integer
,
default
=
0
)
chunk_count
=
Column
(
Integer
,
default
=
0
)
created_at
=
Column
(
DateTime
,
default
=
datetime
.
utcnow
)
created_at
=
Column
(
DateTime
,
default
=
datetime
.
utcnow
)
# ══════════════════════════════════════════════════════
# GitLab CE Integration Models
# ══════════════════════════════════════════════════════
class
GitLabConfig
(
Base
):
__tablename__
=
"gitlab_configs"
id
=
Column
(
String
(
36
),
primary_key
=
True
,
default
=
new_id
)
gitlab_url
=
Column
(
String
(
500
),
nullable
=
False
)
access_token_enc
=
Column
(
String
(
500
),
nullable
=
False
)
default_namespace
=
Column
(
String
(
200
),
nullable
=
True
)
is_active
=
Column
(
Boolean
,
default
=
True
)
created_at
=
Column
(
DateTime
,
default
=
datetime
.
utcnow
)
updated_at
=
Column
(
DateTime
,
default
=
datetime
.
utcnow
,
onupdate
=
datetime
.
utcnow
)
class
GitLabOperation
(
Base
):
__tablename__
=
"gitlab_operations"
id
=
Column
(
String
(
36
),
primary_key
=
True
,
default
=
new_id
)
operation_type
=
Column
(
String
(
50
),
nullable
=
False
)
status
=
Column
(
String
(
20
),
default
=
"pending"
)
project_id
=
Column
(
Integer
,
nullable
=
True
)
project_name
=
Column
(
String
(
200
),
nullable
=
True
)
branch
=
Column
(
String
(
200
),
nullable
=
True
)
payload
=
Column
(
Text
,
nullable
=
False
)
result
=
Column
(
Text
,
nullable
=
True
)
chat_id
=
Column
(
String
(
36
),
nullable
=
True
)
message_id
=
Column
(
String
(
36
),
nullable
=
True
)
created_by
=
Column
(
String
(
36
),
ForeignKey
(
"users.id"
),
nullable
=
False
)
approved_by
=
Column
(
String
(
36
),
nullable
=
True
)
created_at
=
Column
(
DateTime
,
default
=
datetime
.
utcnow
)
executed_at
=
Column
(
DateTime
,
nullable
=
True
)
class
GitLabAuditLog
(
Base
):
__tablename__
=
"gitlab_audit_log"
id
=
Column
(
String
(
36
),
primary_key
=
True
,
default
=
new_id
)
operation_id
=
Column
(
String
(
36
),
nullable
=
True
)
action
=
Column
(
String
(
100
),
nullable
=
False
)
details
=
Column
(
Text
,
nullable
=
True
)
user_id
=
Column
(
String
(
36
),
nullable
=
True
)
created_at
=
Column
(
DateTime
,
default
=
datetime
.
utcnow
)
\ No newline at end of file
backend/routes/gitlab_routes.py
0 → 100644
View file @
dbe0dcba
This diff is collapsed.
Click to expand it.
backend/services/gitlab_service.py
0 → 100644
View file @
dbe0dcba
This diff is collapsed.
Click to expand it.
frontend/src/App.jsx
View file @
dbe0dcba
...
@@ -7,26 +7,20 @@ import LoginPage from "./pages/LoginPage";
...
@@ -7,26 +7,20 @@ import LoginPage from "./pages/LoginPage";
import
ChatPage
from
"./pages/ChatPage"
;
import
ChatPage
from
"./pages/ChatPage"
;
import
AdminPage
from
"./pages/AdminPage"
;
import
AdminPage
from
"./pages/AdminPage"
;
import
KnowledgePage
from
"./pages/KnowledgePage"
;
import
KnowledgePage
from
"./pages/KnowledgePage"
;
import
GitLabPage
from
"./pages/GitLabPage"
;
import
{
Flame
}
from
"lucide-react"
;
import
{
Flame
}
from
"lucide-react"
;
export
default
function
App
()
{
export
default
function
App
()
{
const
{
state
,
dispatch
}
=
useApp
();
const
{
state
,
dispatch
}
=
useApp
();
const
[
authChecked
,
setAuthChecked
]
=
useState
(
!
state
.
token
);
const
[
authChecked
,
setAuthChecked
]
=
useState
(
!
state
.
token
);
// Connect streamManager to store dispatch
useEffect
(()
=>
{
useEffect
(()
=>
{
streamManager
.
setDispatch
(
dispatch
);
streamManager
.
setDispatch
(
dispatch
);
},
[
dispatch
]);
},
[
dispatch
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
state
.
token
)
{
if
(
!
state
.
token
)
{
setAuthChecked
(
true
);
return
;
}
setAuthChecked
(
true
);
if
(
state
.
user
)
{
setAuthChecked
(
true
);
return
;
}
return
;
}
if
(
state
.
user
)
{
setAuthChecked
(
true
);
return
;
}
(
async
()
=>
{
(
async
()
=>
{
try
{
try
{
const
user
=
await
getMe
(
state
.
token
);
const
user
=
await
getMe
(
state
.
token
);
...
@@ -52,14 +46,13 @@ export default function App() {
...
@@ -52,14 +46,13 @@ export default function App() {
);
);
}
}
if
(
!
state
.
token
)
{
if
(
!
state
.
token
)
return
<
LoginPage
/>;
return
<
LoginPage
/>;
}
return
(
return
(
<
Routes
>
<
Routes
>
<
Route
path=
"/admin"
element=
{
<
AdminPage
/>
}
/>
<
Route
path=
"/admin"
element=
{
<
AdminPage
/>
}
/>
<
Route
path=
"/knowledge"
element=
{
<
KnowledgePage
/>
}
/>
<
Route
path=
"/knowledge"
element=
{
<
KnowledgePage
/>
}
/>
<
Route
path=
"/gitlab"
element=
{
<
GitLabPage
/>
}
/>
<
Route
path=
"/*"
element=
{
<
ChatPage
/>
}
/>
<
Route
path=
"/*"
element=
{
<
ChatPage
/>
}
/>
</
Routes
>
</
Routes
>
);
);
...
...
frontend/src/api.js
View file @
dbe0dcba
This diff is collapsed.
Click to expand it.
frontend/src/components/Sidebar.jsx
View file @
dbe0dcba
This diff is collapsed.
Click to expand it.
frontend/src/pages/GitLabPage.jsx
0 → 100644
View file @
dbe0dcba
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment