AI Prompt
↓
File SQL chuẩn MySQL/MariaDB
↓
Import vào MySQL qua phpMyAdmin
↓
m2a_v2.php đọc metadata database
↓
Sinh file AppGini .axp
↓
Mở bằng AppGini
↓
Generate code ứng dụng
↓
Deploy lên web server
Hãy thiết kế MySQL/MariaDB schema tương thích tốt với tool m2a_v2.php để convert sang AppGini AXP.
Yêu cầu bắt buộc:
1. Chỉ tạo BASE TABLE, không tạo VIEW để import vào AppGini.
Nếu cần view báo cáo, đặt ở section riêng cuối file và ghi chú không import view vào AppGini.
2. Mỗi bảng phải có primary key rõ ràng:
- Ưu tiên cột `id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY`
- Không dùng bảng không có primary key.
3. Dùng InnoDB, utf8mb4:
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
4. Tất cả bảng phải có TABLE COMMENT bằng caption người dùng đọc được.
Ví dụ:
COMMENT='Hóa đơn'
5. Tất cả cột phải có COLUMN COMMENT bằng caption đẹp để m2a.php dùng làm field caption.
Ví dụ:
invoice_number VARCHAR(100) NULL COMMENT 'Số hóa đơn'
6. Foreign key phải khai báo thật bằng CONSTRAINT:
- Cột FK nên đặt dạng `{entity}_id`
- Ví dụ `customer_id INT UNSIGNED NULL`
- Có index cho FK.
- Có CONSTRAINT FOREIGN KEY (...) REFERENCES parent_table(id)
- Dùng ON UPDATE CASCADE.
- Dùng ON DELETE SET NULL cho quan hệ optional, ON DELETE CASCADE cho detail/log child.
7. Bảng lookup/master nên có các cột dễ làm caption:
- `code` hoặc `{entity}_code`
- `name` hoặc `{entity}_name`
- m2a.php sẽ ưu tiên `{base}_name`, `{base}_code`, `name`, `title`, `code`.
8. Kiểu dữ liệu nên map tốt sang AppGini:
- ID/FK: INT UNSIGNED hoặc BIGINT UNSIGNED
- Text ngắn: VARCHAR(n)
- Text dài: TEXT/LONGTEXT
- Số tiền: DECIMAL(18,2)
- Tỷ lệ: DECIMAL(8,4)
- Ngày: DATE
- Ngày giờ: DATETIME
- Boolean: TINYINT(1) NOT NULL DEFAULT 0/1
- File upload: VARCHAR(255) NULL COMMENT 'File ...'
- JSON nên dùng LONGTEXT, không dùng JSON native nếu muốn AppGini xử lý mượt.
9. Default value:
- Số có thể dùng DEFAULT 0 hoặc 0.00.
- DATETIME tạo mới dùng DEFAULT CURRENT_TIMESTAMP.
- DATETIME cập nhật dùng DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP.
- Hạn chế default string nếu không thật cần thiết vì AppGini có thể validate default khác MySQL.
- Nếu cần default string, ghi chú để set trong AppGini sau.
10. Không dùng:
- composite primary key
- generated columns
- trigger bắt buộc
- stored procedure
- CHECK phức tạp
- enum/set nếu có thể thay bằng lookup table
- view trong danh sách import AppGini
11. Output cần gồm:
- CREATE DATABASE IF NOT EXISTS ...
- USE ...
- SET FOREIGN_KEY_CHECKS = 0
- DROP VIEW IF EXISTS ... nếu có
- DROP TABLE IF EXISTS theo thứ tự child trước parent
- SET FOREIGN_KEY_CHECKS = 1
- CREATE TABLE parent/master trước
- INSERT seed data cho lookup/master nếu cần
- CREATE TABLE transaction/detail sau
- section optional views ở cuối, ghi chú không import view vào AppGini
Hãy tạo SQL hoàn chỉnh, có comment tiếng Việt cho table/column, tối ưu để m2a.php convert sang AppGini mà ít phải chỉnh tay nhất.
Nghiệp vụ cần thiết kế: hệ thống quản lý hóa đơn đầu vào.
Bao gồm:
- Nhà cung cấp
- Hóa đơn
- Dòng hàng hóa/dịch vụ trên hóa đơn
- Thuế suất
- Trạng thái xử lý hóa đơn
- File hóa đơn gốc
- Người duyệt
- Lịch sử xử lý
- Có CREATE DATABASE và USE database hay chưa
- Có primary key cho tất cả bảng hay chưa
- Có TABLE COMMENT và COLUMN COMMENT hay chưa
- Foreign key có khai báo bằng CONSTRAINT thật hay chưa
- Có dùng enum, json native, generated column, trigger hoặc view lẫn vào phần import không
- Thứ tự CREATE TABLE có hợp lý không
http://localhost/phpmyadmin
Import → chọn file .sql → Go
m2a_v2.php
C:\wamp64\www\
http://localhost/m2a_v2.php
http://localhost/m2a_v2.php
Host: localhost
Port: 3306
User: root
Password:
Database: tên_database_vừa_import
- Danh sách table
- Danh sách column
- Kiểu dữ liệu
- Primary key
- Foreign key
- Comment của table
- Comment của column
File → Open
- Caption của table
- Caption của field
- Lookup field
- Parent/children relationship
- Field type cho date, datetime, money, file upload
- Required field
- Default value
- Table permissions
- Detail view layout
- Filters
- Quick search fields
Generate → chọn thư mục output → OK
C:\wamp64\www\tên_ứng_dụng\
http://localhost/tên_ứng_dụng/
Tạo database quản lý hóa đơn
CREATE TABLE suppliers (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
supplier_code VARCHAR(50) NULL COMMENT 'Mã nhà cung cấp',
supplier_name VARCHAR(255) NOT NULL COMMENT 'Tên nhà cung cấp'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Nhà cung cấp';
status ENUM('draft', 'approved', 'rejected')
CREATE TABLE invoice_statuses (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
status_code VARCHAR(50) NOT NULL COMMENT 'Mã trạng thái',
status_name VARCHAR(100) NOT NULL COMMENT 'Tên trạng thái'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Trạng thái hóa đơn';
status_id INT UNSIGNED NULL COMMENT 'Trạng thái'
invoice_file VARCHAR(255) NULL COMMENT 'File hóa đơn'
ocr_raw_text LONGTEXT NULL COMMENT 'Nội dung OCR gốc'
ai_extract_json LONGTEXT NULL COMMENT 'Kết quả AI trích xuất dạng JSON'
customer_id INT UNSIGNED NULL COMMENT 'Khách hàng',
INDEX idx_invoices_customer_id (customer_id),
CONSTRAINT fk_invoices_customer
FOREIGN KEY (customer_id) REFERENCES customers(id)
ON UPDATE CASCADE
ON DELETE SET NULL
CREATE DATABASE IF NOT EXISTS app_demo
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE app_demo;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS invoice_items;
DROP TABLE IF EXISTS invoices;
DROP TABLE IF EXISTS suppliers;
DROP TABLE IF EXISTS invoice_statuses;
SET FOREIGN_KEY_CHECKS = 1;
CREATE TABLE invoice_statuses (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
status_code VARCHAR(50) NOT NULL COMMENT 'Mã trạng thái',
status_name VARCHAR(100) NOT NULL COMMENT 'Tên trạng thái'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Trạng thái hóa đơn';
INSERT INTO invoice_statuses (status_code, status_name) VALUES
('draft', 'Nháp'),
('pending', 'Chờ duyệt'),
('approved', 'Đã duyệt'),
('rejected', 'Từ chối');
CREATE TABLE suppliers (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
supplier_code VARCHAR(50) NULL COMMENT 'Mã nhà cung cấp',
supplier_name VARCHAR(255) NOT NULL COMMENT 'Tên nhà cung cấp',
tax_code VARCHAR(50) NULL COMMENT 'Mã số thuế',
phone VARCHAR(50) NULL COMMENT 'Điện thoại',
email VARCHAR(255) NULL COMMENT 'Email',
address TEXT NULL COMMENT 'Địa chỉ'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Nhà cung cấp';
CREATE TABLE invoices (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
supplier_id INT UNSIGNED NULL COMMENT 'Nhà cung cấp',
status_id INT UNSIGNED NULL COMMENT 'Trạng thái',
invoice_number VARCHAR(100) NULL COMMENT 'Số hóa đơn',
invoice_date DATE NULL COMMENT 'Ngày hóa đơn',
subtotal DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT 'Tiền trước thuế',
tax_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT 'Tiền thuế',
grand_total DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT 'Tổng thanh toán',
invoice_file VARCHAR(255) NULL COMMENT 'File hóa đơn',
note TEXT NULL COMMENT 'Ghi chú',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Ngày tạo',
updated_at DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'Ngày cập nhật',
INDEX idx_invoices_supplier_id (supplier_id),
INDEX idx_invoices_status_id (status_id),
CONSTRAINT fk_invoices_supplier
FOREIGN KEY (supplier_id) REFERENCES suppliers(id)
ON UPDATE CASCADE
ON DELETE SET NULL,
CONSTRAINT fk_invoices_status
FOREIGN KEY (status_id) REFERENCES invoice_statuses(id)
ON UPDATE CASCADE
ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Hóa đơn';
CREATE TABLE invoice_items (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
invoice_id INT UNSIGNED NOT NULL COMMENT 'Hóa đơn',
item_name VARCHAR(255) NOT NULL COMMENT 'Tên hàng hóa dịch vụ',
unit_name VARCHAR(50) NULL COMMENT 'Đơn vị tính',
quantity DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT 'Số lượng',
unit_price DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT 'Đơn giá',
line_total DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT 'Thành tiền',
INDEX idx_invoice_items_invoice_id (invoice_id),
CONSTRAINT fk_invoice_items_invoice
FOREIGN KEY (invoice_id) REFERENCES invoices(id)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Dòng hóa đơn';
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
- Dựng nhanh prototype
- Thiết kế ứng dụng CRUD nội bộ
- Chuẩn hóa database trước khi đưa vào AppGini
- Tạo các hệ thống quản lý có nhiều bảng liên kết
- Làm bản demo cho khách hàng trong thời gian ngắn
- Bộ prompt mẫu cho từng loại ứng dụng
- Ví dụ SQL hoàn chỉnh cho CRM, ITSM, quản lý hóa đơn, quản lý kho
- Checklist kiểm tra file .axp sau khi convert
- Cách tối ưu m2a_v2.php để nhận diện caption, lookup và field type tốt hơn
$query = "SELECT * FROM users WHERE id = 1";
$result = sql($query, $eo);
while ($row = db_fetch_assoc($result)) {
echo $row['username'];
}
$username = sqlValue("SELECT username FROM users WHERE id = 1");
echo $username ? $username : "Không tìm thấy";
$result = sql("SELECT * FROM users", $eo);
while ($row = db_fetch_assoc($result)) {
echo $row['username'] . " - " . $row['email'];
}
sql("INSERT INTO users (username) VALUES ('john')", $eo);
echo "ID mới: " . db_insert_id();
$memberInfo = getMemberInfo();
echo $memberInfo ? $memberInfo['username'] : "Chưa đăng nhập";
if (is_allowed("users", 1, "edit")) {
echo "Có quyền chỉnh sửa";
} else {
echo "Không có quyền";
}
$input = makeSafe($_POST['username']);
$query = "SELECT * FROM users WHERE username = '$input'";
$description = htmlSpecialChars($_POST['description']);
echo $description;
$tables = getTableList();
print_r($tables);
$options = [
'to' => 'user@example.com',
'subject' => 'Chào mừng',
'message' => 'Chào mừng bạn!'
];
sendmail($options);
require_once('../hooks/config.php');
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
$memberInfo = getMemberInfo();
if (!$memberInfo || !is_allowed("users", null, "view")) {
http_response_code(403);
echo json_encode(['error' => 'Access denied']);
exit;
}
$query = "SELECT id, username, email FROM users";
$result = sql($query, $eo);
$users = [];
while ($row = db_fetch_assoc($result)) {
$users[] = $row;
}
http_response_code(200);
echo json_encode($users);
}
display_errors = On
post_max_size = 100M
upload_max_filesize = 100M
date.timezone = "Asia/Ho_Chi_Minh"
<VirtualHost _default_:80>
ServerName localhost
DocumentRoot "${INSTALL_DIR}/www"
DirectoryIndex index.php index.html index.htm
<Directory />
Require all denied
Options None
AllowOverride None
</Directory>
<Directory "${INSTALL_DIR}/www/">
Options +FollowSymLinks +Indexes
AllowOverride All
Require all granted
</Directory>
<Directory "${INSTALL_DIR}/apps/phpmyadmin5.2.1/">
Require local
</Directory>
</VirtualHost>
ServerSignature Off
ServerTokens Prod
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPassword';
FLUSH PRIVILEGES;
$cfg['Servers'][$i]['AllowNoPassword'] = false;
Username: ladmin
Password: appginivn2025
/var/www/htmlhttp://localhost:8080your-appgini-project/
├── admin/
├── images/
├── hooks/
├── api/v1/
│ ├── api.php
│ ├── auth.php
│ ├── config.php
│ ├── db_connection.php
│ ├── login.php
│ └── permissions.php
└── ... (các file AppGini khác)
extension=mysqli
extension=mbstring
extension=pdo_mysql